Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ISHS Civil Complaint Board (인곽 민원 창구)

A complaint board for members of Incheon Science High School (students and teachers). Anyone in the school can file a complaint anonymously, support others' complaints with a daily-limited upvote, and get answers from teachers and staff, whose comments carry a visible badge. The goal is a transparent, democratic channel for raising issues inside the school.

Identity is verified against the school's Riro School (리로스쿨) portal, which has no official API, so a small companion service logs in on the user's behalf and returns only their name, student number, generation, and role. Passwords are used at the moment of login and never stored.

Repository layout

├── riro-auth/   FastAPI microservice that authenticates against Riro School
│                by mimicking a browser login and parsing the profile page
├── web/         Main application (Next.js 15 App Router, Prisma, PostgreSQL)
└── 리로그인/     Korean design document for the Riro login flow

What it does today

  • Anonymous complaints. Complaints, votes, and comments never expose the author's name, student number, or user ID in API responses. Only comments by staff are marked, with a 교사 (teacher) badge.
  • Daily-limited upvotes. Each user can hold at most 10 active votes per day; duplicate votes on the same complaint are blocked by a unique constraint, and cancelling a vote restores the quota immediately.
  • Automatic archiving. A daily batch (npm run aging) increments a counter for the top 3 complaints by vote count; after 7 days in the top 3, a complaint is moved to the archive and leaves the main ranking.
  • Moderation. An admin dashboard allows hiding comments, suspending users, and deleting complaints. Suspended users cannot log in or post.

Tech stack

  • web/ — Next.js 15.3 (App Router, edge runtime on every API route and dynamic page), React 19, TypeScript, Tailwind CSS 4, Prisma 6 with the Neon serverless driver adapter against PostgreSQL, jose for signed JWT session cookies. Deployed to Cloudflare Pages via @cloudflare/next-on-pages (see web/DEPLOY.md).
  • riro-auth/ — Python, FastAPI, requests + BeautifulSoup for scraping the Riro School login and profile pages. Runs separately (any VPS or container host); ships with a Dockerfile.

Quick start

Full instructions, including the environment variables and database options, are in SETUP.md. The short version:

# Terminal A — auth service
cd riro-auth
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --port 8000   # port 5000 conflicts with macOS AirPlay

# Terminal B — web app
cd web
docker compose up -d           # local PostgreSQL, or point DATABASE_URL elsewhere
npm install
cp .env.example .env           # set SESSION_SECRET (openssl rand -base64 32)
npm run db:push
npm run seed
npm run dev                    # http://localhost:3000

For local development you can skip the Riro login entirely: with ALLOW_DEV_LOGIN=true in .env, the password dev logs in any ID. IDs starting with T become teachers, and hataewook/하태욱 becomes the admin.

Deployment

The web app targets Cloudflare Pages (build with npm run pages:build); riro-auth must be hosted separately. The full guide — infrastructure, environment variables, edge runtime requirements, security checklist — is in web/DEPLOY.md.

Status

Early-stage school project under active development. Core flows (login, complaints, voting, comments, archiving, admin dashboard) are implemented; rate limiting, monitoring, and backups are not in place yet (see the "known limitations" table in web/DEPLOY.md).

About

Anonymous civil complaint board for Incheon Science High School — Riro School login, daily-limited voting, teacher responses, auto-archiving (Next.js + FastAPI)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages