# The Guardianship kit — who acts for whom: children, carers, consents and emergency contacts

> `Osysharp.Guardianship` links a person to the people who look after them. A parent adds a child (an account the child cannot sign in to yet), invites a second guardian by address, answers the app's consent forms for the child and keeps their emergency contacts and the people who may collect them; staff read all of it on site. Each link has a standing — acts for them, kept informed, ended — that changes by itself on the day the child comes of age. The app writes its own rules with one policy, `ActsForDependant`.

<!-- id: security-guardianship-kit · area: security · stability: preview · html: https://osysharp.com/reference/security/guardianship-kit/ -->

## Summary        {#summary}
`use Osysharp.Guardianship@0;` adds who looks after whom. The app says who runs it and who reads it on site, and builds
its own rules on `ActsForDependant`:

```osy syntax
policy ManagesGuardianships => IsDesk;
policy SeesFamilies => IsDesk || IsInstructor;
policy MakesManagedAccounts => IsAuthenticated;      // Osysharp.UserAccounts: who may add a child
policy BooksFor(Principal person) => person == user || ActsForDependant(person);
```

## Signature      {#signature}
```osy syntax
virtual policy ManagesGuardianships => false;
virtual policy SeesFamilies => ManagesGuardianships;
virtual policy MayLinkAsGuardian(Principal guardian, Principal dependant) => guardian != dependant;
public policy ActsForDependant(Principal dependant);      // a guardian who acts for them
public policy KeptInformedOf(Principal dependant);        // …or is kept informed
public policy ActsForSomeone;   public policy LooksAfterSomeone;   // the `when` beside them: is the caller a guardian at all
app.Guardianship = new GuardianshipSetup { AgeOfMajority = 18, AtMajority = GuardianStanding.Ended,
                                           InvitationValidFor = TimeSpan.FromDays(14), Mails = new GuardianshipMails() };

Guardianship AddDependant(string name, DateOnly? bornOn = null, GuardianRelationship relationship = Parent, string careNotes = "");
Guardianship LinkGuardian(Principal guardian, Principal dependant, GuardianRelationship r = Parent, GuardianStanding s = Acting);
Guardianship ChangeStanding(Guardianship link, GuardianStanding standing, string reason = "");
GuardianInvitation InviteGuardian(Principal dependant, string address, GuardianRelationship r = Parent, GuardianStanding s = Acting);
Guardianship AcceptGuardianInvitation(GuardianInvitation i);   void DeclineGuardianInvitation(…);   void WithdrawGuardianInvitation(…);
void SetBornOn(DependantProfile p, DateOnly bornOn);   void DeclareOfAge(DependantProfile p);   void HandOverAccount(Principal d, string address);
Consent AnswerConsent(Principal person, ConsentForm form, ConsentAnswer answer);   bool HasConsent(Principal person, string key);
ConsentForm ReviseConsentForm(ConsentForm form, string wording);   List<ConsentForm> ConsentsOwed(Principal person);
List<EmergencyContact> EmergencyContactsOf(Principal person);   List<string> MayCollectNames(Principal person);
int AgeAt(DateOnly bornOn, DateOnly on);   bool NeedsGuardian(DateOnly bornOn, DateOnly? on = null);   bool IsMinor(Principal person);
// events: GuardianLinked · GuardianStandingChanged · GuardianInvited · ConsentAnswered · DependantCameOfAge
// pages: /family (FamilyScreen) · /family/lookup (FamilyLookup, SeesFamilies)
```

## Description    {#description}

### Nobody makes themself somebody's guardian      {#links}
A link is made in one of three ways: a guardian **adds a child** (`AddDependant` — the child gets an account through
Osysharp.UserAccounts' `MakeManagedAccount`, and the caller acts for them); somebody **accepts an invitation** sent to their own
proven address by a guardian who acts, or by an adult for themself; or **the desk links** a guardian it has checked
(`LinkGuardian`). The app's own screening, `MayLinkAsGuardian`, is asked at the first two. A pair is one row, kept when it
ends, so the history of who looked after whom stays.

### Standings, and coming of age      {#standing}
A link **acts for** the person (`ActsForDependant`: book, answer, change), keeps the guardian **informed**
(`KeptInformedOf`: read only), or has **ended**. A guardian may step back and never forward; the person changes it any way
once they decide for themself, and never while they are a minor; the desk may do anything. Each profile carries a durable
clock that waits for the person's birthday at the app's age of majority and then gives every acting guardian the standing
`AtMajority` names — ended by default, or kept informed. A date set or corrected re-arms it at once; the desk can declare
somebody of age early.

### Consents, against the words      {#consents}
A `ConsentForm` is a question the app asks — photos, first aid, travel. Each answer is a new row holding the version and
words it answered, who answered and when; the latest counts. A minor's guardian answers for them; an adult answers for
themself. Changing a form's words makes a new version, and `HasConsent` is false until it is answered again.

### Emergency contacts, collection and care notes      {#contacts}
The person or a guardian who acts for them keeps the emergency contacts, in calling order, each marked if they may collect
the person. Staff (`SeesFamilies`) read them with the guardians and the care notes. `MayCollectNames` lists the acting
guardians first, then the contacts allowed to collect.

### Handing the account over      {#handover}
`HandOverAccount(child, address)` gives a child's account an address of its own (Osysharp.UserAccounts'
`GiveManagedAccountAnAddress`); once the link mailed there is opened the child signs in themself. Their guardians go on
acting for them until they come of age.

### Personal data      {#privacy}
Dates of birth, care notes (special-category data), emergency contacts and invitation addresses are classified, so their
values never reach the audit trail. With Osysharp.Privacy, `Osysharp.Privacy.Guardianship` arrives by itself and answers
requests for all of it.

## Examples       {#examples}

### A music school where parents read their child's lesson notes      {#example-school}
```osy title="a school's policies, its own rule on KeptInformedOf, and its age of majority" test app=security-guardianship-kit
app MusicSchool {
  use Osysharp.Ui;
  use Osysharp.Workflow;
  use Osysharp.Oauth;
  use Osysharp.Identity@0;
  use Osysharp.Mail@0;
  use Osysharp.Sms@0;
  use Osysharp.EmailTemplates@0;
  use Osysharp.UserAccounts@1;
  use Osysharp.Guardianship@0;
  model "model/**/*.osy";
}

using Osysharp.Identity;
using Osysharp.UserAccounts;
using Osysharp.Guardianship;

[Role] enum SchoolRole { Authenticator, Member, Teacher, Office }
policy IsOffice => RoleGrant.Any(g => g.Member == user && g.Role == SchoolRole.Office);
policy IsTeacher => RoleGrant.Any(g => g.Member == user && g.Role == SchoolRole.Teacher);
policy ManagesGuardianships => IsOffice;
policy SeesFamilies => IsOffice || IsTeacher;
policy MakesManagedAccounts => IsAuthenticated;

app.Accounts = new AccountsSetup { AppName = "Music School", SignupRole = SchoolRole.Member };
app.Guardianship = new GuardianshipSetup { AgeOfMajority = 16, AtMajority = GuardianStanding.Informed };

/// A teacher's note: the pupil reads it, and so does anyone who looks after them.
entity LessonNote {
  [Required] Principal Pupil;
  [Required, MaxLength(400)] string Text;
  security {
    allow read when IsAuthenticated where Pupil == user;
    allow read when LooksAfterSomeone where KeptInformedOf(Pupil);
    allow read, create when IsTeacher;
  }
}

/// A parent adds their child and answers the school's photo consent for them.
void Enrol(string name, DateOnly bornOn) {
  var link = AddDependant(name, bornOn);
  var photos = ConsentForm.FirstOrDefault(f => f.Key == "photos");
  if (photos != null) { AnswerConsent(link.Dependant, photos, ConsentAnswer.Given); }
}
```

## See also       {#see-also}
- [The UserAccounts kit — sign-in done properly, once](https://osysharp.com/reference/security/accounts-kit/) — the managed account a child is given, and handing it over
- [The ClassBookings kit — classes, courses and lessons with places, a waiting list and a register](https://osysharp.com/reference/scheduling/class-bookings-kit/) — booking classes for the children a guardian acts for
- [The Privacy kit — erasure that keeps only what the company must or may](https://osysharp.com/reference/security/privacy-kit/) — privacy requests, which Osysharp.Privacy.Guardianship answers for this kit
