feat: add Terms & Conditions checkbox to signup (refs #4)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 4m38s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped

- Add terms_agreements table for legal audit trail
- Create terms-agreement feature capsule with repository
- Modify signup to create terms agreement atomically
- Add checkbox with PDF link to SignupForm
- Capture IP, User-Agent, terms version, content hash
- Update CLAUDE.md documentation index

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Eric Gullickson
2026-01-03 12:27:45 -06:00
parent 0391a23bb6
commit dec91ccfc2
14 changed files with 390 additions and 15 deletions

View File

@@ -18,6 +18,9 @@ const signupSchema = z
.regex(/[A-Z]/, 'Password must contain at least one uppercase letter')
.regex(/[0-9]/, 'Password must contain at least one number'),
confirmPassword: z.string(),
termsAccepted: z.literal(true, {
errorMap: () => ({ message: 'You must agree to the Terms & Conditions to create an account' }),
}),
})
.refine((data) => data.password === data.confirmPassword, {
message: 'Passwords do not match',
@@ -42,8 +45,8 @@ export const SignupForm: React.FC<SignupFormProps> = ({ onSubmit, loading }) =>
});
const handleFormSubmit = (data: SignupRequest & { confirmPassword: string }) => {
const { email, password } = data;
onSubmit({ email, password });
const { email, password, termsAccepted } = data;
onSubmit({ email, password, termsAccepted });
};
return (
@@ -138,6 +141,31 @@ export const SignupForm: React.FC<SignupFormProps> = ({ onSubmit, loading }) =>
)}
</div>
<div className="flex items-start min-h-[44px]">
<label className="flex items-start cursor-pointer">
<input
{...register('termsAccepted')}
type="checkbox"
className="w-5 h-5 mt-0.5 rounded border-silverstone text-primary-600 focus:ring-abudhabi dark:border-silverstone dark:focus:ring-abudhabi"
aria-label="I agree to the Terms and Conditions"
/>
<span className="ml-2 text-sm text-avus">
I agree to the{' '}
<a
href="/docs/v2026-01-03.pdf"
target="_blank"
rel="noopener noreferrer"
className="text-abudhabi hover:underline"
>
Terms & Conditions
</a>
</span>
</label>
</div>
{errors.termsAccepted && (
<p className="text-sm text-red-400">{errors.termsAccepted.message}</p>
)}
<div className="pt-4">
<Button type="submit" loading={loading} className="w-full min-h-[44px]">
Create Account

View File

@@ -5,6 +5,7 @@
export interface SignupRequest {
email: string;
password: string;
termsAccepted: boolean;
}
export interface SignupResponse {