Skip to content

Latest commit

 

History

History
173 lines (137 loc) · 9.18 KB

File metadata and controls

173 lines (137 loc) · 9.18 KB

OpenCorde Task Tracker

Organized by phase and week. Check items off as they complete.

Split files (to stay under 300 lines per file):


Phase 1: MVP (Weeks 0-12)

Week 0: AI Scaffolding

Status: COMPLETE

  • Create ReadMeFirst.md
  • Create project-map.yaml
  • Create decisions.md
  • Create all INDEX.md files (in each crate/module as created)
  • Create tasks.md
  • Create quality-gate.md
  • Create CLAUDE.md, .cursorrules, .github/copilot-instructions.md
  • Create Cargo.toml workspace
  • Create docker-compose.yml
  • Create .env.example
  • Create LICENSE (AGPL-3.0)
  • Create .gitignore
  • Initialize git repository
  • Verify cargo check --workspace passes
  • Verify cargo clippy --workspace -- -D warnings passes
  • Verify cargo fmt --check passes

Weeks 1-2: Foundation

Status: COMPLETE

Objective: Core types, ID generation, permission system, database schema.

opencorde-core Crate

  • Implement Snowflake ID generator (snowflake.rs — 270 lines)
    • Custom epoch 2024-01-01, 64-bit [42:timestamp][5:worker][5:process][12:sequence]
    • SnowflakeGenerator, Snowflake newtype, Display/FromStr, serde as string
    • 11 unit tests (monotonicity, uniqueness, conversions, timestamp extraction)
  • Implement permission bitfield system (permissions.rs + permission_compute.rs)
    • 27 permission flags via bitflags crate (general, text, voice, admin)
    • PermissionOverwrite, OverwriteType, compute_permissions()
    • Admin bypass, role/member overwrite precedence
    • 9 unit tests
  • Create core model types (8 model files in models/)
    • user.rs, server.rs, channel.rs, message.rs, member.rs, role.rs, invite.rs, voice_state.rs
    • All Serialize/Deserialize/Debug/Clone, comprehensive tests
    • 41 model tests
  • Create shared event types (gateway.rs + events.rs)
    • 19 GatewayEvent variants (lifecycle, messages, typing, presence, voice, servers, channels, members)
    • Serde tagged JSON: {"type": "EventName", "data": {...}}
    • 8 serialization tests

opencorde-db Crate

  • Create database connection pool (lib.rs — create_pool, run_migrations, health_check)
  • Create 9 SQL migrations
    • 001_users, 002_servers, 003_channels, 004_messages, 005_roles
    • 006_server_members + member_roles, 007_invites, 008_voice_states, 009_files
    • Proper indexes, foreign keys, cascading deletes
  • Implement user repository (user_repo.rs — full CRUD)
  • Implement server repository (server_repo.rs — full CRUD + list_by_user)
  • Implement channel repository (channel_repo.rs — full CRUD + list_by_server)
  • Implement message repository (message_repo.rs — full CRUD + cursor pagination)
  • Implement member repository (member_repo.rs — membership + role assignment)

opencorde-api Crate (Setup Only)

  • Create Axum skeleton with health check (GET /api/v1/health)
    • main.rs: tokio::main, config loading, DB pool, migration, router
  • Add request ID middleware (UUID per request via MakeRequestUuid)
  • Add CORS middleware (strict prod, permissive dev)
  • Create error handling (ApiError enum + IntoResponse, 7 variants)
  • Set up tracing (JSON in prod, pretty in dev, env filter from RUST_LOG)
  • Config from env vars with defaults and secret masking

Quality Gate

  • cargo check --workspace — passes
  • cargo clippy --workspace -- -D warnings — 0 warnings
  • cargo fmt --check — passes
  • cargo test --workspace — 99 tests passing (76 core + 8 db + 15 api)
  • No file exceeds 300 lines (max: 275)
  • All files have structured doc headers
  • INDEX.md files updated

Infrastructure

  • Verify docker-compose services start on dev server
  • Install Rust toolchain on dev server (192.168.140.140)
  • Install pnpm on dev server

Phase 1-3 Summary (Complete as of 2026-03-22)

All 26/26 browser tests passing. 30 migrations applied. Full feature set deployed at opencorde.com. See ReadMeFirst.md for complete feature list.

Sprint 2026-03-22: SMTP + Docs

  • Fix validation test bug (validate_channel_type type 3 = Stage is valid; test type 4)
  • Implement lettre SMTP in email.rs (replaces logging stub)
  • Add SMTP vars to .env.example
  • Update ReadMeFirst.md, tasks.md, tasks-future.md

Sprint 0: Full Security Hardening (2026-03-24 to 2026-03-25)

  • 0a: Permission enforcement — wired compute_effective_permissions() into all routes (messages, channels, reactions, threads, members, invites, roles, webhooks)
  • 0b: Per-endpoint rate limiting — axum-governor with per-IP token buckets; 5/min login, 3/min register, 5/sec messages, 10/min uploads, 60/min global
  • 0c: JWT refresh token rotation — JTI (UUID v4) stored in refresh_tokens table; single-use; stolen token detection revokes all sessions; migration 041
  • 0d: File upload security — MIME allowlist, per-category size limits (image 8MB, video 100MB, other 25MB), magic-byte verification, EXIF stripping (img-parts, lossless)
  • 0e: XSS audit — custom markdown renderer already safe (escapeHtml() + code-block extraction); no DOMPurify needed
  • 0f: HTTP security headers middleware — X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, Content-Security-Policy
  • 0g: SQL injection audit — zero format!() in repos; all queries use .bind() parameterization
  • 0h: 2FA (TOTP) — migration 042, POST /auth/2fa/enable + verify + DELETE /auth/2fa, login requires totp_code when enabled; client: TwoFactorSetup.svelte, login TOTP step, settings section
  • 0i: Password security audit — Argon2id confirmed, 8-char minimum enforced, delete account requires current password
  • 0j: Audit log completeness — added member.kick, member.role_assign, member.role_remove; existing: ban, unban, timeout, timeout_removed

Sprint 1: Missing WebSocket Events (2026-03-25)

  • 1a: ws/dispatch.rs — add member_server_ids: HashSet<i64> param; route ChannelCreate/Update/Delete, RoleCreate/Update/Delete, MemberUpdate, ServerUpdate to server-member filter
  • 1b: ws/handler/main_loop.rs — thread member_server_ids through to should_dispatch
  • 1c: ws/handler/lifecycle.rs — load user's server IDs via server_repo::list_by_user; pass to run_main_loop
  • 1d: ws/events.rs — add 7 new event builders (channel_update, channel_delete, role_create, role_update, role_delete, member_update, server_update)
  • 1e: channels/handlers.rs — broadcast ChannelCreate/Update/Delete after successful CRUD
  • 1f: servers/handlers/crud.rs — broadcast ServerUpdate after successful PATCH
  • 1g: roles.rs — broadcast RoleCreate/Update/Delete + MemberUpdate (assign/unassign)
  • 1h: client stores — initChannelListeners, initRoleListeners, initMemberListeners, initServerListeners; called from +layout.svelte

Sprint 2: Message Edit/Delete UI (2026-03-25)

  • 2a: messages store — added editMessage(messageId, content) and deleteMessage(messageId) API calls
  • 2b: MessageContextMenu.svelte (new) — extracted context menu buttons + added Edit (✏) and Delete (🗑) for own messages only
  • 2c: MessageList.svelte — added onEdit/onDelete/currentUserId props, inline edit mode (textarea, Enter saves, Esc cancels), uses MessageContextMenu component
  • 2d: channel +page.svelte — wired handleEditMessage, handleDeleteMessage, passes currentUserId to MessageList

Tracking Notes

  • Each task must pass quality-gate.md before completion
  • Update ReadMeFirst.md with progress
  • Blockers noted inline with BLOCKED: reason

Sprint 3: Slowmode Enforcement (2026-03-25)

  • 3a: migration 043_slowmode.sql — ALTER TABLE channels ADD COLUMN slowmode_delay INT NOT NULL DEFAULT 0
  • 3b: channel_repo.rs — add slowmode_delay to ChannelRow; update_channel accepts slowmode_delay param
  • 3c: channels/types.rs — add slowmode_delay to ChannelResponse and UpdateChannelRequest
  • 3d: channels/handlers.rs — map slowmode_delay in channel_row_to_response; clamp 0–21600; pass to update_channel
  • 3e: send_list.rs — after channel fetch, if slowmode_delay > 0 query user's last message; return RateLimited{retry_after} if too soon
  • 3f: types.ts — add slowmode_delay to Channel interface
  • 3g: ChannelSettingsModal.svelte — add slowmodeDelay state, number input (0–21600), include in PATCH body
  • 3h: channel +page.svelte — pass channelSlowmode to modal, update store on save

Sprint 4: User Profile Popup (2026-03-25)

  • 4a: role_repo.rs — add list_by_member(user_id, server_id) → Vec via JOIN on member_roles
  • 4b: roles.rs — GET /servers/{server_id}/members/{user_id}/roles returns Vec
  • 4c: UserProfilePopover.svelte (new) — avatar, status dot, bio, role chips, Send Message DM button
  • 4d: MessageList.svelte — avatar div and author name wrapped in clickable buttons, open popover on click
  • 4e: channel +page.svelte — pass serverId prop to MessageList

Last updated: 2026-03-25