The server fronts everything with Caddy (container root-caddy-1), has no
Dockge and no Traefik, and keeps compose stacks in /docker — not
/opt/stacks. Every traefik.* label in this compose file was inert, so the
container would build and run while never being routed.
Join the external `web` network Caddy is on so it can reach the container
by name (info-share-spot:3000) and publish no host port. Routing now
lives in /root/Caddyfile on the server.
Rewrite DEPLOY.md against the real topology, including the Caddyfile
validate-before-reload step — a bad Caddyfile takes down every site on
the box, and Caddy serves a stale in-memory config until something
reloads it, which hides the breakage until the next restart.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Plans, accommodations, related services, annual goals with progress
monitoring, meetings/team, and signed documents — plus a compliance
list and dashboard alerts for annual-review and triennial re-evaluation
dates (overdue in red, due-within-30-days in amber).
Access is tiered because special-education records are need-to-know
under FERPA:
FULL admin, the plan's case manager, the student's parents
IMPL the above, plus any teacher of the student — accommodations
and services only, never eligibility or meeting notes
RLS is row-level and every app role is the same Postgres role
(`authenticated`), so column grants cannot separate the tiers. The
split is therefore physical: confidential fields live in plan_details,
plan_goals, plan_meetings and plan_documents rather than as columns on
student_plans.
The UI asks the database which tier applies via the same predicates the
policies use (can_view_plan_full / can_edit_plan) instead of re-deriving
the rules client-side.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Safari doesn't reliably fire onChange for native date pickers, so read dob/
start/agreement dates directly from the input refs when saving.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Attendance filter, gradebook assignment date, and tuition entry date now use
defaultValue (with a remount key where the field resets after submit).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Theme primary -> Bayside navy (#06315a) in light & dark, sidebar + focus ring
- Bayside logo in the sidebar, login page, and public intake header
- Login title -> Bayside Academy
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Safari's native <input type="date"> gets reset by React's controlled value,
so picked dates never reached state. Make date inputs uncontrolled
(defaultValue + onChange) in the profile, academics, and public intake forms.
Header now shows grade level instead of a single class.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- intake_tokens table (server-only via service role)
- Server functions: createIntakeToken (admin), getIntakeToken (public validate),
submitIntake (public write + mark used, 14-day one-time tokens)
- Public /intake/$token full intake form (no login) with valid/used/expired states
- Student profile (admin): generate link, copy, and email-to-parent (mailto)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Native date pickers blur/refocus the window, which triggered a React Query
refetch mid-edit and wiped the in-progress date. Disable refetchOnWindowFocus,
and make profile/academics edits work on a snapshot with functional state
updates so a background refetch can't clobber input.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Parents and teachers are now view-only on student data (profile, guardians,
pickups, curriculum logins). Writes restricted to admins in RLS and the UI;
read access unchanged. Portal logins for parents/students are view-only.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The classes query filtered by teacher_id when isAdmin was momentarily false
(roles not yet loaded) and never refetched — cache key lacked isAdmin. Gate on
!loading and include isAdmin in the query key.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Admin server function (service-role) to create accounts, set role, and
optionally link a parent to a student; wired via env_file (.env.secret)
- Admin > Users: "Add a user" form (teacher/parent/admin) with one-time temp password
- Student profile > Family: "Parent portal access" — create + link a parent login
- Parents can now edit their own child's profile (RLS-scoped); internal notes stay admin-only
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Profile / Family & pickup / Academics tabs now render a clean read-only
view with an Edit toggle that reveals the editable form (Save/Cancel/Done).
Guardian/pickup/login cards show summaries in view mode, inputs in edit mode.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
students.tsx was the list AND the parent of students.new / students.$id but
rendered no <Outlet/>, so child routes never showed. Make students.tsx an
Outlet layout and move the list to students.index.tsx. Add an errorComponent
to students.new as a safety net.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Migration: student intake fields (health, academic, dismissal, agreement),
student_guardians + student_curriculum_logins tables, extend authorized_pickups
(alt_phone, notes, kind) with RLS mirroring existing policies
- New /students/new full-page multi-section form (replaces the add dialog)
- Students list links to the full page; regenerate Supabase types
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Point .env + supabase/config.toml at EDU (qgmcpounpkgsjlwosjdi)
- Replace Lovable Google-OAuth shim with native supabase.auth.signInWithOAuth
- Remove src/integrations/lovable and @lovable.dev/cloud-auth-js dependency
- Drop .lovable metadata; gitignore supabase/.temp
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>