Skip to content

Add date domain, validation, Supabase reconciliation, generation safety, and CI/E2E tests - #10

Merged
Armand9999 merged 2 commits into
mainfrom
codex/familiarize-with-codebase-mdekfg
Jun 15, 2026
Merged

Add date domain, validation, Supabase reconciliation, generation safety, and CI/E2E tests#10
Armand9999 merged 2 commits into
mainfrom
codex/familiarize-with-codebase-mdekfg

Conversation

@Armand9999

Copy link
Copy Markdown
Owner

Motivation

  • Harden runtime and data contracts by introducing explicit domain types and validation for dates, profiles, generated plans, and auth flows.
  • Make generated AI content safe to persist by validating JSON structures and switching to non-destructive upserts for persisted plans.
  • Reconcile the repository contract with an existing Supabase project by providing a migration, Row Level Security policies, and typed database artifacts.
  • Improve quality and reliability with deterministic CI and Playwright end-to-end coverage for public authentication journeys.

Description

  • Added domain and validation libraries: app/lib/date.ts, app/lib/profile.ts, app/lib/generated-plans.ts, app/lib/auth.ts, app/lib/profile-options.ts, and a generated-compatible DB contract app/lib/database.types.ts and used them across code paths.
  • Refactored date handling to use a local YYYY-MM-DD date key (getLocalDateKey / parseDateKey), updated UI and client APIs to pass validated date keys, and removed fragile toISOString().split('T')[0] usage.
  • Made AI generation deterministic and safe by using openai JSON response formats, parsing and validating with Zod, and persisting with upsert (non-destructive) in app/lib/workout-generator.ts and app/protected/profile/meal-plan/action.ts; added parsing helpers and stricter schemas for exercises and meals.
  • Introduced typed Supabase helpers and middleware changes: typed utils/supabase/{client,server,middleware}.ts to use Database, improved cookie handling, and changed middleware to fail-closed for protected routes while keeping public routes available.
  • Added a reconciliation migration and preflight checks in supabase/migrations/20260611170000_reconcile_fitness_schema.sql and supabase/preflight/... to align the remote schema, create save_profile_with_tde RPC, apply RLS, and enforce uniqueness constraints.
  • Implemented password recovery and reset flows (app/forgot-password, app/reset-password, and app/auth/confirm/route.ts) with safe redirect handling via getSafeRedirectPath.
  • UI and small UX updates: replaced raw img with next/image in NavBar, removed Google font integration for a simpler CSS fallback, and improved profile, meal plan, and workout components to surface validation and errors.
  • Quality and tests: added Node unit tests under tests/*.test.ts, Playwright e2e spec e2e/public-auth.spec.ts, Playwright config playwright.config.ts, CI workflow .github/workflows/quality.yml, and updated package.json scripts and tsconfig.test.json to run typechecked unit tests and E2E runs.
  • Documentation and housekeeping: expanded README.md, added .env.example, updated .gitignore, added supabase/config.toml, and adjusted eslint.config.mjs to ignore generated artifacts.

Testing

  • Added a unit test suite covering auth schemas, date domain, profile schema, generated-plan validation, TDE calculation, Supabase migration contract, and client contract (tests/*.test.ts) and a Playwright e2e spec for public auth journeys (e2e/public-auth.spec.ts).
  • Added a deterministic Playwright configuration in playwright.config.ts and CI workflow quality.yml that runs npm run check, npm run build, and npm run test:e2e and uploads failure artifacts on CI failure.
  • No automated tests were executed as part of this changelist; the commit includes the tests and CI configuration so they will run in the configured CI pipeline.

Codex Task

@vercel

vercel Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
fitness-app Ready Ready Preview, Comment Jun 15, 2026 6:51pm

Request Review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1e31271653

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/lib/auth.ts
}

export function getSafeRedirectPath(value: string | null, fallback = '/') {
return value?.startsWith('/') && !value.startsWith('//') ? value : fallback

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject backslash-prefixed callback redirects

When a successful authentication callback supplies next=/%5Cattacker.example, URLSearchParams decodes it to /\attacker.example, which this check accepts. Next.js then emits that value as the redirect destination, and browsers normalize the backslash so the navigation goes to https://attacker.example/, leaving the authentication callback vulnerable to an open redirect. Validate the destination by resolving it against the configured site origin and requiring the resolved origin to match.

Useful? React with 👍 / 👎.

Comment on lines +25 to +27
where user_id is null or date is null or workout_type is null or duration_minutes is null
or duration_minutes <= 0 or difficulty is null or exercises is null
or jsonb_typeof(exercises) <> 'array';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Check constrained workout values during preflight

When an existing workout plan has a non-null but unsupported workout_type or difficulty—possible because the previous generator persisted unvalidated model output—this documented preflight returns no row, but the reconciliation migration later adds enum-like check constraints and aborts. Include the allowed-value predicates here so a zero-row preflight actually guarantees that the migration can apply.

Useful? React with 👍 / 👎.

Comment on lines +73 to +76
return (
<div className="max-w-xl mx-auto p-6 bg-red-50 dark:bg-red-900/20 rounded-lg">
<p className="text-red-600 dark:text-red-400">The saved meal plan is invalid. Generate a new plan to continue.</p>
</div>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep regeneration available for invalid saved plans

When a legacy meal plan fails the newly strict parser, this early return removes the New Plan button rendered later on the page, even though the message instructs the user to generate one. Because getMeal continues returning the same existing row, affected users cannot recover through the UI without manually deleting data; provide a regeneration action in this error state.

Useful? React with 👍 / 👎.

}

const profile = ProfileSchema.parse(profileData)
const prompt = `Create a personalized ${duration}-minute bodyweight workout plan for a user with goal ${profile.goal}, gender ${profile.gender}, age ${profile.age}, and activity level ${profile.activity_level}. Return a JSON object with workout_type, difficulty, and a non-empty exercises array. Each exercise must include name and instructions, and may include sets, reps, duration, and rest.`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Tell the model the required workout enum values

When the model returns natural values such as "bodyweight circuit" or "moderate", generation now fails because GeneratedWorkoutPlanSchema only accepts the configured workout-type and difficulty enums, but this replacement prompt no longer lists those allowed values as the previous prompt did. Since JSON mode only guarantees valid JSON, include the exact enum contract or use a structured schema response to avoid intermittent user-visible generation failures.

Useful? React with 👍 / 👎.

@Armand9999
Armand9999 merged commit a3686fb into main Jun 15, 2026
2 of 3 checks passed
@Armand9999
Armand9999 deleted the codex/familiarize-with-codebase-mdekfg branch June 15, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant