feat(time-rounding-rules): Settings-Option: Rundung für Time-Entries (5/15/30 min) [tsc:fail]

This commit is contained in:
Dennis (via Claude+Gemma) 2026-05-23 06:36:29 +02:00
parent c0e8e3611e
commit 68158b7cb7
4 changed files with 49 additions and 3 deletions

View File

@ -1,5 +1,8 @@
{
"completed_features": [],
"current_feature": "invoicing-stub",
"started_at": "2026-05-23T06:33:48.406343"
"current_feature": "time-rounding-rules",
"started_at": "2026-05-23T06:33:48.406343",
"attempted_features": [
"invoicing-stub"
]
}

View File

@ -1459,3 +1459,22 @@ src/index.ts(27,25): error TS2769: No overload matches this call.
Overload 2 of 3, '(plugin: FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
Argument of type 'Promise<FastifyMultipartPlugin>' is not assignable to parameter of type 'FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
Type 'Promise<FastifyMultipartPlugin>' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTy
- `06:35:10` **INFO** Committed feature invoicing-stub
- `06:35:10` **INFO** Pushed: rc=0
## Phase-3 Feature: time-rounding-rules (2026-05-23 06:35:10)
- `06:35:10` **INFO** Description: Settings-Option: Rundung für Time-Entries (5/15/30 min)
- `06:35:10` **INFO** Generating apps/api/src/db/schema.ts (ERWEITERT — füge `roundingMinutes: integer('rounding_minutes').notNull…)
- `06:35:40` **INFO** wrote 3445 chars in 29.4s (attempt 1)
- `06:35:40` **INFO** Generating apps/web/src/pages/Settings.tsx (ERWEITERT — füge Select-Field 'Time-Rounding: keine / 5min / 15min / 3…)
- `06:36:27` **INFO** wrote 5786 chars in 47.5s (attempt 1)
- `06:36:27` **INFO** Running tsc --noEmit on api…
- `06:36:29` **WARN** tsc errors:
src/index.ts(27,25): error TS2769: No overload matches this call.
Overload 1 of 3, '(plugin: FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
Argument of type 'Promise<FastifyMultipartPlugin>' is not assignable to parameter of type 'FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
Type 'Promise<FastifyMultipartPlugin>' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProvider>, opts: { ...; }, done: (err?: Error | undefined) => void): void'.
Overload 2 of 3, '(plugin: FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
Argument of type 'Promise<FastifyMultipartPlugin>' is not assignable to parameter of type 'FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
Type 'Promise<FastifyMultipartPlugin>' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTy

View File

@ -55,6 +55,7 @@ export const appSettings = pgTable("app_settings", {
workspaceName: text("workspace_name").notNull().default("EmberClone"),
defaultBillable: boolean("default_billable").notNull().default(true),
weekStart: integer("week_start").notNull().default(1),
roundingMinutes: integer("rounding_minutes").notNull().default(0),
updatedAt: timestamp("updated_at").notNull().defaultNow()
})

View File

@ -8,6 +8,7 @@ export default function Settings() {
const [workspaceName, setWorkspaceName] = useState('');
const [defaultBillable, setDefaultBillable] = useState(false);
const [weekStart, setWeekStart] = useState('Monday');
const [timeRounding, setTimeRounding] = useState('0');
const { data: settings, isLoading, refetch } = useQuery({
queryKey: ['settings'],
@ -20,7 +21,12 @@ export default function Settings() {
});
const updateMutation = useMutation({
mutationFn: async (data: { workspaceName: string; defaultBillable: boolean; weekStart: string }) => {
mutationFn: async (data: {
workspaceName: string;
defaultBillable: boolean;
weekStart: string;
timeRounding: number
}) => {
return api.updateSettings(data);
},
onSuccess: async () => {
@ -37,6 +43,7 @@ export default function Settings() {
setWorkspaceName(settings.workspaceName || '');
setDefaultBillable(settings.defaultBillable ?? false);
setWeekStart(settings.weekStart || 'Monday');
setTimeRounding((settings.timeRounding ?? 0).toString());
}
}, [settings]);
@ -46,6 +53,7 @@ export default function Settings() {
workspaceName,
defaultBillable,
weekStart,
timeRounding: parseInt(timeRounding, 10),
});
};
@ -113,6 +121,21 @@ export default function Settings() {
<option value="Sunday">Sonntag</option>
</select>
</div>
{/* Time Rounding */}
<div className="space-y-2">
<label className="text-sm font-medium text-slate-700">Zeiterfassung-Rundung</label>
<select
value={timeRounding}
onChange={(e) => setTimeRounding(e.target.value)}
className="w-full px-3 py-2 border border-slate-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all bg-white"
>
<option value="0">Keine Rundung</option>
<option value="5">5 Minuten</option>
<option value="15">15 Minuten</option>
<option value="30">30 Minuten</option>
</select>
</div>
</div>
<div className="pt-4 flex justify-end">