Add NFC chore submission feature and enhance family settings

- Introduced NFC support for chore submissions, allowing specific person credit after Head of Household approval.
- Updated family settings to include NFC base URL, scan cooldown, and confirmation page options.
- Enhanced chore management with options for anyone to complete chores and NFC link generation.
- Improved API endpoints for handling NFC tokens and chore submissions.
- Updated readme to reflect new NFC features and settings.
This commit is contained in:
2026-03-31 10:28:27 -05:00
parent 9a78c4564e
commit f14de0b7e1
21 changed files with 779 additions and 21 deletions
+51
View File
@@ -97,3 +97,54 @@ function normalizePeopleList($raw): array {
}
return $out;
}
/**
* @param array<string, mixed> $person
* @return array<string, mixed>
*/
function migrateLegacyPersonRow(array $person): array {
if (!array_key_exists('nfc_submit_token_hash', $person) || !is_string($person['nfc_submit_token_hash'])) {
$person['nfc_submit_token_hash'] = '';
}
if (!array_key_exists('nfc_submit_token_updated_at', $person) || !is_string($person['nfc_submit_token_updated_at'])) {
$person['nfc_submit_token_updated_at'] = '';
}
return $person;
}
/**
* @param array<int, array<string, mixed>> $people
* @return array<int, array<string, mixed>>
*/
function migrateAllPeople(array $people): array {
$out = [];
foreach ($people as $person) {
if (!is_array($person)) {
continue;
}
$out[] = migrateLegacyPersonRow($person);
}
return $out;
}
/**
* @param array<int, array<string, mixed>> $people
* @return array{index:int, person:array<string, mixed>}|null
*/
function findPersonBySubmitToken(array $people, string $token): ?array {
$token = trim($token);
if ($token === '') {
return null;
}
$candidateHash = hash('sha256', $token);
foreach ($people as $index => $person) {
$storedHash = trim((string) ($person['nfc_submit_token_hash'] ?? ''));
if ($storedHash === '') {
continue;
}
if (hash_equals($storedHash, $candidateHash)) {
return ['index' => (int) $index, 'person' => $person];
}
}
return null;
}