fix(api): serialize dated writes after request body parsing
This commit is contained in:
@@ -22,9 +22,12 @@ export class HabitService {
|
||||
private occurrencesCache = new Map<string, Map<number, (typeof taskOccurrences.$inferSelect)[]>>();
|
||||
private countCache = new Map<string, Map<string, { value: number; carriedFrom: string | null }>>();
|
||||
constructor(readonly db: AppDatabase, readonly user: PublicUser, readonly now: number) {
|
||||
// A different request may update the timezone while this request's body streams in.
|
||||
const timezone = db.select({ timezone: users.timezone }).from(users).where(eq(users.id, user.id)).get()!.timezone;
|
||||
this.user = { ...user, timezone };
|
||||
// Travel west must never reopen or rewrite earlier requirements.
|
||||
const latest = db.select({ date: habits.materializedThrough }).from(habits).where(eq(habits.userId, user.id)).orderBy(desc(habits.materializedThrough)).get()?.date;
|
||||
this.today = [localDate(now, user.timezone), latest ?? ''].sort().at(-1)!;
|
||||
this.today = [localDate(now, this.user.timezone), latest ?? ''].sort().at(-1)!;
|
||||
}
|
||||
owned(id: string): Habit {
|
||||
const cached = this.ownedCache.get(id); if (cached) return cached;
|
||||
@@ -193,7 +196,7 @@ export class HabitService {
|
||||
const config = revision?.config;
|
||||
const future = date > this.today;
|
||||
const tasks = config?.method === 'tasks' && !config.archived && scheduled(config.schedule, date)
|
||||
? record ? this.occurrences(id).get(record.id) ?? []
|
||||
? record ? config.tasks.flatMap(task => (this.occurrences(id).get(record.id) ?? []).filter(occurrence => occurrence.taskId === task.id))
|
||||
: config.tasks.filter(t => scheduled(t.schedule, date)).map(t => ({ id: null, taskId: t.id, name: t.name, done: false, expiredAt: null, closedAt: null, updatedAt: null })) : [];
|
||||
const due = !!config && !config.archived && scheduled(config.schedule, date) && (config.method !== 'tasks' || tasks.length > 0);
|
||||
const counted = config?.method === 'count' && !future ? this.counts(id).get(date) : undefined;
|
||||
@@ -219,7 +222,7 @@ export class HabitService {
|
||||
if (detail.method === 'count' ? !('count' in input) : !('done' in input)) throw new ApiError(422, 'Input does not match the method on this date');
|
||||
this.countCache.delete(id);
|
||||
this.db.transaction(() => {
|
||||
this.db.insert(progressEvents).values({ dayId: record.id, before: { count: record.count, done: record.done }, after: input, createdAt: this.now }).run();
|
||||
this.db.insert(progressEvents).values({ dayId: record.id, before: { count: detail.value, done: record.done, loggedCount: record.countSet ? record.count : null, carriedFrom: detail.carriedFrom }, after: input, createdAt: this.now }).run();
|
||||
this.db.update(habitDays).set('count' in input ? { ...input, countSet: true } : input).where(eq(habitDays.id, record.id)).run();
|
||||
});
|
||||
this.invalidate(id);
|
||||
|
||||
Reference in New Issue
Block a user