Sidebar screen now primarily displays user-related information
and derives three render states from loginStatus + currentUser.isVip:
- guest (notLoggedIn): welcome panel + Sign in / Sign up entries
- member (logged in, no VIP): user info card + Get VIP CTA + Log out
- vip (logged in, VIP): user info card with VIP badge + Manage VIP CTA
+ Log out
Adds UserView.isVip (default false), patches user-machine.toView()
to populate it, and introduces three presentational components
(GuestPanel, UserInfoCard, VipCta) co-located under src/app/sidebar.
Preserves existing UserInit + logout-redirect behavior.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix chat components barrel to properly export all component modules
- Remove interceptor exports from API services barrel
- Regenerate store barrel files (auth, chat, sidebar, user) using barrelsby
Add a new /subscription route showing three VIP membership plans (Monthly,
Quarterly, Annual) with a pink→peach banner, per-plan gradient price bars,
a benefits card, a mock activate CTA, and an agreement checkbox.
- New reusable <Checkbox /> in src/app/_components/core for the legal
agreement toggle
- Hardcoded SUBSCRIPTION_PLANS constant in src/data/constants
- New SubscriptionScreen composed of 7 colocated components (back link,
user row, banner, plan card, benefits card, CTA button) with CSS
Modules matching the existing design-token system
- Route registered as protected and reached from /sidebar "Membership"
- Mock CTA: window.alert + router.push(/chat) — no payment calls
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove unused `quotaWarningThreshold` and `warningThreshold` getter from `GuestChatQuota` DTO
- Apply get-or-init pattern in `ChatStorage.getGuestDailyChatQuota` and `getGuestTotalQuota`: when no existing value, initialize with DTO defaults (`threshold` = max per day, `totalQuotaDefault`) and return the seeded data
- Fall back to original `null` result if initialization write fails
- Consolidate logging strategy: drop per-actor trace logs in `chat-machine.ts`, keep business-decision logs in 3 assign actions, move all actor ENTRY/API/DONE chains to `chat-machine.actors.ts` and helper load logs to `chat-machine.helpers.ts`
Update implementation_plan.md with a detailed refactor plan that splits
`chatInitActor` into two independent actors (`loadQuotaActor` +
`loadHistoryActor`) and redesigns the history loading flow to follow
local → network → save semantics so the UI sees local data first,
then network data.
Key changes outlined in the plan:
- Add new events: `ChatQuotaLoaded`, `ChatHistoryLocalLoaded`,
`ChatHistoryNetworkLoaded`, `ChatHistorySyncDone`
- Remove dead-code `ChatInit` event
- Extend `ChatState` with `quotaLoaded` and `historyLoaded` flags
- Use an `always` barrier in `guestSession.initializing` and
`userSession.initializing` so both tasks must complete before
transitioning to `ready`
- Guest init runs `loadQuota` + `loadHistory` in parallel; non-guest
init runs `chatWebSocket` + `loadHistory` as independent tasks
Also adds `implementation_plan` to .gitignore.
Drop the QuotaDialog component invocation in chat-screen along with
its useState/useEffect wiring, and delete the component files. Update
JSDoc in chat-screen and routes to reflect the removed consumer.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Split `chatInitActor` into `loadQuotaActor` (guest quota fetch) and `loadHistoryActor` (local → network → save sync), and add `quotaLoaded` / `historyLoaded` state flags so the UI can display loading status during the new local-first history hydration flow. Also drop the now-unused `ChatInit` event and pipe Next.js stdout/stderr to a persistent log file in the post-receive hook for easier troubleshooting.
Without cd, git rev-parse --show-toplevel fails inside .git/
with 'must be run in a work tree', causing init_log_file to
write to /logs/post-receive.log (root path), and copy_env_by_branch
to fail with 'cannot stat env-example/...'.
Remove the repo top-level navigation logic and its accompanying
explanatory comments from the post-receive hook. The previous code
used `git rev-parse --absolute-git-dir` and `dirname` to determine
and `cd` into the repository's top-level directory, which is no
longer needed. The hook now starts directly with the nvm setup,
making the script leaner and easier to maintain.
The $0-based dirname trick didn't work because git invokes
hooks with just the basename (e.g., 'post-receive'), not the
absolute path. Use 'git rev-parse --absolute-git-dir' instead,
which works even when CWD is inside .git/.
Replace complex pnpm-finding fallback with the same NVM loading
syntax used in ~/.bashrc. Removes the multiple candidate-path
fallback loop in favor of a clean shell snippet.
git-receive-pack may invoke hook with CWD inside .git/,
where 'git rev-parse --show-toplevel' errors with
'must be run in a work tree'. Use $(dirname $0) instead.
Comment out `src/router/index.ts` and `src/router/proxy.ts` to temporarily
disable the Next.js 16 proxy (auth-driven redirects) and router re-exports.
This effectively turns off the centralized route guard logic and stops the
proxy from intercepting requests until further iteration.
- cd to repo toplevel first (defensive: git-receive-pack CWD may differ)
- source nvm or directly find pnpm binary if not in PATH
- prepend pnpm's dir to PATH so build/start work
Root cause: post-receive hook was not being triggered on push.
With core.hooksPath=.githooks (relative), git-receive-pack
resolved the path incorrectly. Also pnpm wasn't in PATH during
non-interactive shell invocation.
Move the file-local Helpers block (readGuestId) to auth-helpers.ts and the
Actors block (authRepo + 7 fromPromise actors) to auth-actors.ts. Public API
(authMachine, AuthEvent, AuthState, initialState, AuthMachine) is unchanged;
auth-context.tsx and the barrel index.ts need no edits.
Refactor the post-receive deployment hook from a linear script into
discrete functions (init_log_file, write_metadata_header,
copy_env_by_branch, run_build, stop_existing_next, launch_next) for
better readability, maintainability, and error isolation.
Key changes:
- Remove `set -e` so deploy errors don't block git push; each step
handles its own failures (missing env, build failure
- Select env template per branch: main → .env.production, test/dev → .env.local
- Skip env copy on unknown branches with warning log
- Revert pnpm run start output to /dev/null (debugging complete)
- Reorder LOG_FILE definition before env-copy block so case branches can log
- Add per-environment AUTH_SECRET (dev/test/prod) for next-auth v4 JWT signing
- Temporarily redirect next start stdout/stderr to LOG_FILE in post-receive hook for server error debugging
Move repository-managed git hooks from `git_hooks/` to `.githooks/` to follow the conventional hidden-directory naming, and add a graceful shutdown step in `post-receive` that terminates any running `next start` / `next-server` processes (SIGTERM → wait 2s → SIGKILL → wait 1s) before relaunching, avoiding EADDRINUSE port conflicts so the freshly built code actually takes effect. README updated to reference the new path.
Move the NextAuth v4 configuration from the route handler
(src/app/api/auth/[...nextauth]/route.ts) into a dedicated module
(src/lib/auth/auth.ts) to establish a single source of truth. The
route file now simply re-exports the handler from the shared
module, keeping provider setup, JWT/session callbacks, and
environment variable references in one reusable location.
- Inline NextAuth v4 handler directly in `[...nextauth]/route.ts`, removing
the `@/lib/auth/nextauth` abstraction layer
- Add Google/Facebook providers with JWT/session callbacks that expose
`idToken` and `accessToken` on the session for backend exchange
- Refactor `AuthPlatform` from constructor-based to static methods
(`googleSignIn()` / `facebookSignIn()`)
- Update `auth-machine.ts` and layout comment reference to match new structure
- Align with original Dart `nextauth-helpers.{googleLogin, facebookLogin}()`
naming and keep persistence concerns (unstorage, backend, custom cookies)
out of scope for this iteration
Add console.log instrumentation across the guest login pipeline (auth-machine, authRepository, authApi) to trace request lifecycle and surface Zod parsing failures with detailed issue info. Useful for diagnosing lastMessageAt schema mismatches.
Update WORKTREE_PATH in pre_release_web.sh and release_web.sh to reference the new frontend subdirectory location, aligning scripts with the current project folder structure.
- Add error handling to `cd` command to exit with a clear message if the worktree directory is missing
- Change relative `cp` source/destination paths to absolute paths prefixed with `$WORKTREE_PATH`, ensuring files are always read from and written to the intended worktree regardless of the current working directory
- Update inline comments to reflect the new absolute-path behavior in both `pre_release_web.sh` and `release_web.sh`
- Reorganize env example files into a dedicated env-example/ directory for clarity
- Update .gitignore to ignore env files (with examples now in env-example/)
- Unify CDN credentials (CF_ZONE_ID / CF_API_TOKEN) to be sourced from .env.local in both test and production deploys
- Update git_hooks/post-receive to copy production env example from new location
- Update deploy scripts (pre_release_web.sh, release_web.sh) to copy the appropriate env example into .env.local before building
- Update _deploy_lib.sh purge_cdn_cache to source from .env.local instead of .env
Update WORKTREE_PATH in release scripts to include "nextjs" prefix in directory names (cozsweet-nextjs-test and cozsweet-nextjs-main) and remove outdated comment blocks from both pre_release_web.sh and release_web.sh.