- C-3: inject setupLimiter into NewAdminAPI instead of package-level global
- H-5: generateRandomKey returns error instead of panicking
- H-6: replace init() bcrypt with sync.Once lazy initialization
- M-2: remove unsafe-inline from admin CSP script-src and style-src
- M-3: sanitize upload filenames (strip control chars, truncate to 255)
- M-5: truncate User-Agent to 512 bytes before storing as device
- M-10: MaxBodySizeUnless uses prefix matching instead of exact path
- M-12: wrap seedExistingDatabase in a single transaction
- M-13: use errors.Is for EOF check in upload handler
- M-14: log writeJSON encoding errors instead of discarding
- M-16: standardize error codes to INTERNAL_ERROR across all handlers
Server fixes:
- voice_leave: broadcast voice_leave even on DB error so peers don't see ghost users (H1)
- migrate: record migration inside transaction for atomicity (H2)
- password: use init() with panic for dummyHash to catch bcrypt init failures (M1)
- password: replace //nolint:errcheck with explicit _ = discard (M2)
- handlers: clarify edit permission comment, fix error message wording (M3)
- auth_handler: distinguish duplicate username (400) from DB error (500) (M4)
Client fixes:
- media: revert YouTube oEmbed to browser fetch — no need to disable cert verification (C1)
- messages.store: fix prependMessages cap to keep newest messages, not oldest (H5)
- ChannelSidebar: ref-count globalDragAc to prevent multi-instance teardown race (H6)
- attachments: replace console.error with project logger (M6)
- ws: clarify lastSeq reset comment to match actual behavior (M5)
Fix 70+ errcheck violations by adding explicit error discards (`_ =`)
for unchecked return values across test helpers and deferred Close()
calls. Remove unused `senderID` field from broadcastMsg and unused
`defaultCleanupMaxWindow` const. Apply De Morgan's law, remove empty
branch, and simplify redundant type declaration per staticcheck.
- Scaffold Go module (github.com/owncord/server) with all package dirs
- config: koanf-based YAML loader with env var overrides, default generation
- db: pure-Go SQLite (modernc, no CGO), WAL mode, FK enforcement, full
15-table schema from SCHEMA.md including FTS5 and idempotent migrations
- auth/tls: ECDSA P-256 self-signed cert generation, LoadOrGenerate for
all 4 TLS modes (self_signed, acme, manual, off)
- api: chi router with request ID middleware, /health and /api/v1/info
- main: graceful shutdown (30s timeout), structured slog JSON logging
- Stubs for ws, storage, admin packages ready for Phase 2+
Test coverage: api 100%, auth 85.7%, db 82.4%, config 80.6%
Binary: chatserver.exe 12MB, GOOS=windows GOARCH=amd64