Files
XQKqueue/server
brother7 17d296263c 修复账号禁用及队列场次状态规则
问题与需求:后台禁用员工后旧会话仍可继续访问;实时队列跨天误读昨日场次;项目暂停后需禁止取号但允许叫号。

修复思路:账号权限变更时撤销会话并同步前端登录态;实时查询统一按项目时区当天场次过滤;拆分取号与叫号的状态校验,并补充前后端及 PostgreSQL 回归测试。
2026-07-30 12:02:05 +08:00
..
2026-07-12 15:53:24 +08:00
2026-07-12 15:53:24 +08:00
2026-07-14 19:15:13 +08:00
2026-07-12 15:53:24 +08:00
2026-07-12 15:53:24 +08:00

Queue API

Go 1.26 modular-monolith API for the scenic queue system. It uses the standard library HTTP router, GORM, PostgreSQL, versioned embedded SQL migrations and database-backed sessions.

Local run

  1. Start PostgreSQL and create the database in DATABASE_URL.

  2. Copy .env.example to .env, replace both cryptographic keys, and export the variables. Keys must decode to exactly 32 random bytes.

  3. Run go run ./cmd/api. With MIGRATE_ON_START=true, embedded migrations run under a PostgreSQL advisory lock.

  4. Seed the local demo users, projects, queues, batches, devices and audit data with:

    ADMIN_PASSWORD='replace-me' go run ./cmd/seed
    

    The command is repeatable and prints the demo display and visitor paths. It resets only the DEMO, RAFT and CABLE projects. Default users are the protected xqkwljtadmin account and staff; override the staff credential and primary-project values with ADMIN_USERNAME, STAFF_USERNAME, ADMIN_PASSWORD, PROJECT_CODE and PROJECT_NAME.

For a production release, run go run ./cmd/migrate as a separate release Job with MIGRATE_ON_START=false, then rotate the protected administrator password with SUPER_ADMIN_PASSWORD='...' go run ./cmd/bootstrap-admin. Do not run the seed command against production.

POST /api/staff/projects/{id}/tickets and POST /api/staff/projects/{id}/call-next require an Idempotency-Key header. Ticket creation requires an immutable integer party_size inside the project's configured min_party_size / max_party_size range. A call-next request uses { "expected_revision": 12, "mode": "TICKET|PEOPLE", "count": 5 }. TICKET selects up to count consecutive FIFO tickets. PEOPLE selects the longest consecutive FIFO prefix whose total party size does not exceed count; it never splits or skips a ticket and rejects when the first ticket alone is larger than the requested target. Each mode has a separate project-level anti-mistouch maximum.

If a phone already has active tickets, ticket creation returns DUPLICATE_PHONE; repeat with the same request body except allow_duplicate: true and a new idempotency key after the employee confirms.

GET /api/public/projects returns projects currently open for visitor self-service, including each project's allowed party-size range. POST /api/public/projects/{id}/tickets uses the same ticket validation, queue locking and idempotency rules as the staff ticket flow, but returns only the public ticket projection and a private status token. Public ticket creation is rate-limited and audited as PUBLIC_TICKET_CREATED.

POST /api/public/status/search is a temporary non-production operational-test endpoint. It accepts { "phone": "..." } and returns all current active tickets associated with that phone. It is disabled when APP_ENV=production; replace it with OTP or an external identity interface before formal launch.

POST /api/internal/status/search exposes the same active-ticket lookup to trusted backend services in every environment. It accepts { "phone": "..." } and only allows direct peers on private or loopback networks. Do not publish this path through the public Ingress; callers must use the internal service address. Forwarded client-IP headers are intentionally ignored.

Tests

go test ./...
go vet ./...

From the repository root, make test-db creates a disposable PostgreSQL database and runs migration/maintenance integration tests.

Unit tests cover FIFO ticket/people selection, people-ahead ETA, phone normalization, authenticated encryption, token hashing and password hashing. PostgreSQL integration tests run through make test-db against a disposable database.