Skip to content

feat: Slice 0 — Auth + Task Capture Spine - #7

Merged
Muzaffar-codes07 merged 33 commits into
mainfrom
feat/slice-0-auth-task-capture-spine
May 22, 2026
Merged

feat: Slice 0 — Auth + Task Capture Spine#7
Muzaffar-codes07 merged 33 commits into
mainfrom
feat/slice-0-auth-task-capture-spine

Conversation

@Muzaffar-codes07

Copy link
Copy Markdown
Owner

Summary

Smallest end-to-end loop that proves the architecture: signed-in user opens a ⌘K palette, types a task title, presses Enter, and sees it persist in a list — Postgres write and task.created event on the events:tasks Redis Stream.

  • Backend: Task model + Alembic 0003 migration, TaskService dual-write (Postgres + Redis), POST / GET / DELETE /v1/tasks (DELETE is idempotent), user_uuid() uuid5 mapping bridging Google sub → UUID, fakeredis-backed pytest fixtures.
  • Frontend: Next.js BFF proxy at /api/tasks (hardened: 401/400/503/non-JSON guards, 204 short-circuit), React Query v5 provider + useTasks / useCreateTask / useDeleteTask hooks, ⌘K command palette, /dashboard with empty state / list / delete buttons / error UI, Google sign-in landing.
  • Plan + decisions: docs/superpowers/plans/2026-05-18-slice-0-auth-task-capture-spine.md, docs/decisions/2026-05-18-data-layer.md. CURRENT_SLICE.md advanced to Week 3–4 Scaffolding.

Test plan

  • cd apps/api && python -m pytest -q27 passed (auth, validation, persistence, event emission, ordering, user isolation, idempotent delete × 3)
  • pnpm --filter @lockin/web test4 passed (palette: closed renders nothing, trim+submit on Enter, blank guard, reset on reopen)
  • pnpm --filter @lockin/web typecheck → clean
  • pnpm --filter @lockin/web lint → clean
  • cd apps/api && python -m mypy app → clean (strict)
  • Manual smoke test — sign in via Google → ⌘K → type → Enter → verify task in tasks table and task.created entry in XRANGE events:tasks - +, then refresh → row persists

Carried-forward (non-blocking, deferred per plan)

  • Migration 0003/0002 have no DB-side gen_random_uuid() default on id (ORM-only)
  • No transactional outbox — Redis publish-after-commit can theoretically drop an event on failure
  • No monotonic tiebreaker on created_at ordering (very low real-world flake probability)
  • BFF DELETE uses ?id= query string; TODO(week-3-4) marker added to refactor to [id] segment when PATCH lands
  • Local env note: a native Postgres on Windows shadowed Docker's :5432; backend tests run against the native instance (the Docker lockin_test DB is unused). The dev lockin DB needs alembic upgrade head before the manual smoke test.

🤖 Generated with Claude Code

Muzaffar-codes07 and others added 30 commits May 19, 2026 22:07
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Wrap db_client yield in try/finally so dependency_overrides.clear()
  is guaranteed to run even when a test body raises (prevents override
  leaking into later tests via the module-level app singleton)
- Narrow _override_redis annotation from FakeRedis to Redis to match
  the _redis dep it overrides; add `from redis.asyncio import Redis`
- Guard _test_db_url() against a malformed DATABASE_URL that would
  silently produce an invalid connection string

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace `import app.db.models` with `from app.db import models as _models`
so the name `app` is not rebound, eliminating 6 mypy errors caused by the
module shadowing the FastAPI instance imported from app.main.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wires the end-to-end visible loop: landing page redirects signed-in
users to /dashboard; dashboard server gate checks auth and delegates
to DashboardClient which renders the task list, empty state, and ⌘K
command palette. Also fixes a pre-existing lint error in CommandPalette
(setState in effect → moved to cleanup return).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Muzaffar-codes07 and others added 2 commits May 20, 2026 13:45
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…torybook static)

Storybook static build artifacts add ~5,800 Parcel-bundled vendor JS nodes
to the knowledge graph with mangled symbol names — pure noise. Excluding
them yields a 92% node-count reduction and lets the LockIn architecture
surface cleanly in graphify-out/graph.html.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@gitguardian

gitguardian Bot commented May 22, 2026

Copy link
Copy Markdown

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

Two CI failures, both fixed in one go (history-clean — no transient
literal credentials):

1. js — @vitejs/plugin-react@4.x is CJS but vitest 3.x bundles Vite 7
   (ESM-only). Bumped to ^5.0.0 (ESM-native) and renamed vitest.config.ts
   to .mts so Node loads the config as ESM. (apps/web has no
   "type": "module", so .ts configs default to CJS and cannot
   require() ESM.) Linux Node 20 rejects the boundary mismatch that
   local Windows Node tolerates.

2. python-api — CI workflow had no Postgres, so the Slice 0 db_client
   fixture (Task 7) couldn't connect to :5432. Start an ephemeral
   Postgres via docker run inside a step, generate a fresh random
   password per run (openssl rand), mask it in logs with ::add-mask::
   and export DATABASE_URL + AUTH_SECRET through $GITHUB_ENV. No literal
   credentials in source — GitGuardian-clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@Muzaffar-codes07
Muzaffar-codes07 force-pushed the feat/slice-0-auth-task-capture-spine branch from 0465f5b to e8d3ec1 Compare May 22, 2026 11:27
@Muzaffar-codes07
Muzaffar-codes07 merged commit 4305668 into main May 22, 2026
8 checks passed
@Muzaffar-codes07
Muzaffar-codes07 deleted the feat/slice-0-auth-task-capture-spine branch May 22, 2026 11:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant