Commit Graph
17 Commits
Author SHA1 Message Date
admin 92da19229a Modified by www.SourceFiles.app 2026-08-07 14:09:53 +00:00
admin d261bea4e8 Modified by www.SourceFiles.app 2026-08-07 05:42:30 +00:00
admin df9fa4992a Modified by www.SourceFiles.app 2026-08-07 04:15:24 +00:00
admin 1cb86273f7 Modified by www.SourceFiles.app 2026-08-07 04:13:15 +00:00
adminandClaude Opus 5 85d87d1c62 Charge tuition automatically from attendance
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>
2026-07-26 09:45:30 -04:00
adminandClaude Opus 5 9d7d18669d Add 504 / IEP plans with tiered confidentiality
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>
2026-07-26 09:14:40 -04:00
adminandClaude Opus 4.8 872eacefc5 Read profile date inputs from the DOM at save (Safari-proof)
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>
2026-07-19 20:01:55 -04:00
adminandClaude Opus 4.8 e95171a0d4 Make remaining date inputs Safari-safe (uncontrolled)
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>
2026-07-19 19:46:33 -04:00
adminandClaude Opus 4.8 471d31cee6 Fix dates not saving on Safari; show grade level under student name
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>
2026-07-19 19:37:07 -04:00
adminandClaude Opus 4.8 90e3c2c188 Add admin-emailed one-time intake links
- 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>
2026-07-19 18:00:39 -04:00
adminandClaude Opus 4.8 eb94c7ec34 Fix student profile dates not saving
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>
2026-07-19 17:50:53 -04:00
adminandClaude Opus 4.8 8880d7a805 Lock student profile editing to admins only
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>
2026-07-19 17:32:45 -04:00
adminandClaude Opus 4.8 8fe6ad00f4 Gradebook: classes, weighted grading, assignments, grades, student role
- Migration: student role, students.user_id, grade_categories/grade_scale
  (school defaults + per-class override), assignments, grades + RLS
- Classes area (nav): list/create classes, class page with Gradebook / Roster /
  Grading setup tabs; teachers see their classes, admins all
- Weighted-category grade calc -> letter scale (shared helper)
- Roster assignment (admin), assignment + grade entry (teacher/admin)
- Student profile: view-only Grades tab (parents/students)
- Portal access: create parent OR student logins linked to the student

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 16:57:27 -04:00
adminandClaude Opus 4.8 73a4e70f0b Parent hand-off: admin creates parent/teacher accounts + portal edit
- 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>
2026-07-19 16:30:56 -04:00
adminandClaude Opus 4.8 894b0722e0 Student profile: read-only view by default, Edit button to edit
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>
2026-07-19 16:21:04 -04:00
adminandClaude Opus 4.8 48cf441cba Profile model: quick-create + full editable student profile
- /students/new: quick create (name + DOB) -> redirects into the profile
- /students/$id: full editable profile with photo upload, and tabs for
  Profile / Family & pickup (guardians, emergency contacts, pickups) /
  Academics (curriculum logins + records) / Attendance / Tuition / Contracts
- Migration: students.photo_path + private student-photos storage bucket
  (admin write, linked-user read); regenerate types

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 16:13:36 -04:00
gpt-engineer-app[bot]andrenee-png eeeae5181a Changes
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
2026-06-30 20:44:37 +00:00