Adds a per-student daily rate (students.daily_tuition_cents) and a trigger
that writes a tuition charge when a student is marked present or late.
Idempotency is the crux. The attendance UI upserts on (student_id, date)
and teachers toggle a status freely — present, absent, present again. A
naive "insert a charge on attendance" trigger bills the family once per
click. So each auto-charge is bound to the attendance row that caused it
via ledger_entries.attendance_id (UNIQUE), which turns the write into an
upsert, lets a change back to absent delete the charge, and cascades the
charge away if the attendance record is deleted.
Manual entries keep attendance_id NULL — Postgres allows unlimited NULLs
in a unique index — so hand-entered charges are untouched and the UI can
tell auto from manual.
A NULL rate (the default) means never auto-charge, so nothing begins
billing until a rate is deliberately set on a student. Existing
attendance is not backfilled: retroactively generating charges against
families' balances should be an explicit decision, not a side effect of
deploying a migration.
The trigger is SECURITY DEFINER because the writer is a teacher marking
attendance while ledger_entries is admin-write under RLS; teachers gain
no general ledger access, only this fixed attendance-derived write.
Verified against the live schema across all eight paths: charge on
present, reversal on absent, no duplicate on re-mark, late billable,
excused free, no rate means no charge, rate change on re-save, and
cascade on attendance delete.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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>
I need a website for school similar to: https://praxipower.com/solutions/
*Attendance - by class would be nice, especially as we expand. A teacher would only see their students.
*Student information: standard contact information. Authorized pick up. Allergies. Photo release (yes/no). Upload signed contracts (this behind an admin wall).
*Tuition ledger card
-Monthly payment plan
-Late pick up
-Activity fees
*Sending text/emails to parents. A lot of our parents communicate via text, so it would be nice to have this feature, but I’m sure it’s limited because of cell phone stuff. But could there be a communication portal? Or… how do doctor’s offices send texts??
*Can they complete documents electronically? I don’t want these public facing, but If I push out a document through the site to current students to secure their spot for next year, could the parent complete that electronically and it automatically populated into the student account? It’s okay to tell me I’m far reaching LOL Maybe that
*Can this be linked to our current website? Could it be behind a parent login wall?
*Calendar (very low on the list…could just be a document that shows the school year at a glance… like BPS basic calendar).
X-Lovable-Edit-ID: edt-c8f62e11-9706-4a04-8b29-68fc71cf8991
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>