aboutsummaryrefslogtreecommitdiff
path: root/src/lib/server/services/routine-actions.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/server/services/routine-actions.ts')
-rw-r--r--src/lib/server/services/routine-actions.ts86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/lib/server/services/routine-actions.ts b/src/lib/server/services/routine-actions.ts
new file mode 100644
index 0000000..b546ec7
--- /dev/null
+++ b/src/lib/server/services/routine-actions.ts
@@ -0,0 +1,86 @@
+import { fail, type ActionFailure } from '@sveltejs/kit';
+import { archive, complete, edit, loadCurrent } from './routines';
+import { parseFormString, parseFrequencyDays } from './validation';
+
+/**
+ * Shared implementations of the routine edit/complete form actions, used by
+ * both the project dashboard (/projects/[id]) and the routine page
+ * (/projects/[projectId]/routine/[routineId]). Guarding and failure messages
+ * are the strictest common denominator: a missing or archived routine is
+ * rejected before any write.
+ */
+
+export type EditRoutineResult =
+ ActionFailure<{ error: string }> | { success: boolean; type?: 'edit' };
+
+export async function editRoutineAction(
+ data: FormData,
+ routineId: number,
+ extra?: { type: 'edit' },
+): Promise<EditRoutineResult> {
+ const current = await loadCurrent(routineId);
+ if (!current) {
+ return fail(400, { error: 'Routine introuvable' });
+ }
+ if (current.archived) {
+ return fail(400, { error: 'Routine archivée' });
+ }
+
+ const name = parseFormString(data.get('name'));
+ if (!name) {
+ return fail(400, { error: 'Le nom est requis' });
+ }
+
+ let frequencyDays: number;
+ try {
+ frequencyDays = parseFrequencyDays(data.get('frequencyDays'));
+ } catch {
+ return fail(400, { error: 'Fréquence invalide' });
+ }
+
+ // The dashboard row form has no description field; only touch it when the
+ // form actually sends one, so list edits never wipe a description.
+ const fields: { name: string; frequencyDays: number; description?: string } =
+ { name, frequencyDays };
+ const description = data.get('description');
+ if (description !== null) {
+ fields.description = description.toString();
+ }
+
+ try {
+ await edit(routineId, fields);
+ } catch {
+ return fail(400, { error: 'Routine introuvable' });
+ }
+ return { success: true, type: extra?.type };
+}
+
+export async function completeRoutineAction(data: FormData, routineId: number) {
+ const current = await loadCurrent(routineId);
+ if (!current) {
+ return fail(400, { error: 'Routine introuvable' });
+ }
+ if (current.archived) {
+ return fail(400, { error: 'Routine archivée' });
+ }
+
+ try {
+ await complete(
+ routineId,
+ parseFormString(data.get('note')),
+ new Date().toISOString(),
+ );
+ } catch {
+ return fail(400, { error: 'Routine introuvable' });
+ }
+ return { success: true };
+}
+
+export async function archiveRoutineAction(routineId: number) {
+ try {
+ await archive(routineId);
+ } catch {
+ return fail(400, { error: 'Routine introuvable' });
+ }
+ return { success: true };
+}