# AFI Scorecard V5 model

## Core hierarchy

Person -> Service Profiles -> Scorecard Membership -> Sessions -> Votes -> Vote Records

### Person
Permanent identity. Images, website and permanent notes belong here. A person is not an office.

### Service profile
One period of service / candidacy for a person. Create a new profile when someone changes office.

Fields: `level`, `office`, `title`, `stateCode`, `seat`, `party`, `startDate`, `endDate`, `firstElected`, `notes`.

### Scorecard
A standalone scoring project such as `119th Congress - House` or `Florida House 2027-28`.

A membership points to both a `personId` and `serviceProfileId` and stores scorecard-specific status:

- `legislativeStatus`
- `electionStatus`
- `primaryRating`
- `nextOffice`
- `nextElectionDate`
- `awards`
- `active`

### Sessions
Each scorecard can have unlimited sessions. Votes belong to a session.

### Votes
Fields include AFI position, date, session, category, key-vote flag and numeric weight (`0.5x`, `1x`, `1.5x`, `2x`, `3x`, etc.).

### Vote records
Per-person values: `Y`, `N`, `PRESENT`, `NV`, `EXCUSED`, `NIO`.

`NIO` = Not In Office and is always excluded from scoring. Service profile dates automatically disable a member for votes outside the profile dates.

## Fast entry

Vote editor supports:

- All Republicans = selected vote
- All Democrats = selected vote
- Everyone else = selected vote
- R YES / D NO
- R NO / D YES
- Everyone YES
- Everyone NO
- Invert Y/N
- Individual exceptions after a preset

## Lifetime score

The admin calculates a person's lifetime score from weighted earned / possible points across every scorecard containing that person. Old service profiles are retained, so office changes do not destroy historical context.

## Server files

- `/data/scorecard-v5.json` complete admin state
- `/data/people/master-people.json` permanent people + service profiles
- `/data/scorecard-index-v5.json` scorecard index
- `/data/scorecards/{scorecard-id}.json` one file per scorecard
