Skip to content

Commit 4cd5b35

Browse files
committed
update plans
1 parent 0b31dbb commit 4cd5b35

9 files changed

Lines changed: 279 additions & 236 deletions

project/plans_archive/PLAN-chat-credits.md

Lines changed: 50 additions & 205 deletions
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,42 @@
22

33
## Current System Analysis
44

5+
## Progress (feat/chat-gpt-5-1)
6+
7+
**Done on this branch**
8+
- Persisted and displayed per-message `creditsUsed` (computed from token usage), enabling cost auditing per assistant response.
9+
- Credits initialization/reset exists server-side via scalar chatbot fields + fixed-period logic (this differs from the JSON sketch in this doc).
10+
11+
**Remaining**
12+
- Reconcile this plan with the current implementation so it matches reality.
13+
- With course↔chatbot many-to-many, decide whether credits are per chatbot or per course↔chatbot context; update schema/unique keys accordingly if per-course.
14+
515
### Existing Structure
616

7-
- `ChatUsageCredits` model tracks credits per participant-chatbot pair
8-
- Credits are decremented when AI responses consume tokens via `CreditsService.decrementCredits()`
9-
- Current implementation initializes new users with **0 credits** (critical gap)
10-
- No automatic reset or refill mechanism exists
11-
- Frontend displays credit progress bar and switches available models based on credit balance
17+
- `ChatUsageCredits` tracks credits per `(participantId, chatbotId)`.
18+
- Credits are initialized and reset via fixed-period logic in `apps/chat/src/services/credits.ts`.
19+
- Credit policy is stored on `Chatbot` as scalar fields: `creditInitialCredits`, `creditResetPeriod`, `creditResetAmount`, `creditMaxCredits`.
20+
- Atomic helpers in `apps/chat/src/utils/transactions.ts` avoid race conditions.
21+
- Frontend uses `/api/chatbots/<chatbotId>/credits` to load `availableModels` + `automaticModelId`.
1222

1323
### Identified Issues
1424

15-
1. **New User Experience**: Students joining a course get 0 credits, blocking immediate access
16-
2. **No Reset Mechanism**: Once credits are consumed, users cannot get more without manual intervention
17-
3. **Missing Configuration**: No way to configure credit policies per chatbot
18-
4. **No Periodic Refresh**: No support for "X credits per week/month" scenarios
25+
1. **Plan/documentation drift**: this document still describes a JSON-based configuration that is no longer used.
26+
2. **Course↔chatbot N:N**: credits are currently chatbot-scoped; keep as-is or decide on course-scoped credits if policy differs by course.
1927

2028
## Implementation Plan
2129

2230
### Phase 1: Database Schema Updates
2331

24-
#### 1.1 Extend Chatbot Model
32+
#### 1.1 Current Chatbot Credit Fields
2533

26-
Add `creditSettings` JSON field to the `Chatbot` model:
34+
Credit policy is defined via scalar fields on `Chatbot`:
2735

2836
```prisma
29-
model Chatbot {
30-
// ... existing fields
31-
32-
// Credit configuration per chatbot
33-
creditSettings Json? // {
34-
// initialCredits: 100,
35-
// resetPeriod: 'weekly',
36-
// resetAmount: 50,
37-
// maxCredits: 100
38-
// }
39-
}
40-
```
41-
42-
**Credit Settings Schema:**
43-
44-
```typescript
45-
interface CreditSettings {
46-
initialCredits: number // Credits given to new users
47-
resetPeriod: 'daily' | 'weekly' | 'biweekly' | 'monthly' | 'none'
48-
resetAmount: number // Credits restored on reset
49-
maxCredits: number // Maximum credits (for partial resets)
50-
}
37+
creditInitialCredits Int
38+
creditResetPeriod CreditResetPeriod
39+
creditResetAmount Int
40+
creditMaxCredits Int
5141
```
5242

5343
#### 1.2 Extend ChatUsageCredits Model
@@ -67,143 +57,29 @@ model ChatUsageCredits {
6757

6858
### Phase 2: Credit Initialization System
6959

70-
#### 2.1 Update CreditsService.getUserCredits()
60+
#### 2.1 Current CreditsService behavior
7161

72-
Current behavior creates 0 credits for new users. Enhanced logic:
62+
See `apps/chat/src/services/credits.ts`:
63+
- Initializes credits using fixed period alignment (`getCurrentPeriodStart`).
64+
- Uses atomic helpers for initialize/reset/decrement.
65+
- Resets happen when `isPeriodExpired()` returns true.
7366

74-
```typescript
75-
static async getUserCredits(
76-
participantId: string,
77-
chatbotId: string
78-
): Promise<UserCredits> {
79-
let credits = await prisma.chatUsageCredits.findUnique({
80-
where: { participantId_chatbotId: { participantId, chatbotId } }
81-
})
67+
#### 2.2 Atomic helpers (current)
8268

83-
if (!credits) {
84-
// Initialize with chatbot's default settings
85-
credits = await this.initializeCredits(participantId, chatbotId)
86-
} else {
87-
// Check if reset is needed
88-
credits = await this.checkAndResetCredits(credits, chatbotId)
89-
}
90-
91-
return {
92-
current: credits.current.toNumber(),
93-
total: credits.total.toNumber()
94-
}
95-
}
96-
```
97-
98-
#### 2.2 Create CreditsService.initializeCredits()
99-
100-
```typescript
101-
static async initializeCredits(
102-
participantId: string,
103-
chatbotId: string
104-
): Promise<ChatUsageCredits> {
105-
const chatbot = await prisma.chatbot.findUnique({
106-
where: { id: chatbotId },
107-
select: { creditSettings: true }
108-
})
109-
110-
const settings = chatbot?.creditSettings as CreditSettings | null
111-
const initialAmount = settings?.initialCredits ?? 10 // default fallback
112-
113-
return await prisma.chatUsageCredits.create({
114-
data: {
115-
participantId,
116-
chatbotId,
117-
total: initialAmount,
118-
current: initialAmount,
119-
periodStartedAt: new Date(),
120-
lastResetAt: new Date(),
121-
resetCount: 0
122-
}
123-
})
124-
}
125-
```
69+
See `apps/chat/src/utils/transactions.ts` for:
70+
- `atomicInitializeCredits`
71+
- `atomicResetCreditsIfNeeded`
72+
- `atomicDecrementCredits`
12673

12774
### Phase 3: Periodic Reset Mechanism
12875

129-
#### 3.1 Reset Period Calculations
130-
131-
```typescript
132-
enum ResetPeriod {
133-
DAILY = 'daily',
134-
WEEKLY = 'weekly',
135-
BIWEEKLY = 'biweekly',
136-
MONTHLY = 'monthly',
137-
NONE = 'none'
138-
}
139-
140-
static shouldResetCredits(
141-
lastResetAt: Date,
142-
resetPeriod: ResetPeriod
143-
): boolean {
144-
const now = new Date()
145-
const timeDiff = now.getTime() - lastResetAt.getTime()
146-
147-
switch (resetPeriod) {
148-
case ResetPeriod.DAILY:
149-
return timeDiff >= 24 * 60 * 60 * 1000 // 24 hours
150-
case ResetPeriod.WEEKLY:
151-
return timeDiff >= 7 * 24 * 60 * 60 * 1000 // 7 days
152-
case ResetPeriod.BIWEEKLY:
153-
return timeDiff >= 14 * 24 * 60 * 60 * 1000 // 14 days
154-
case ResetPeriod.MONTHLY:
155-
// Reset on same day of month (e.g., every 1st of month)
156-
const lastResetMonth = lastResetAt.getMonth()
157-
const currentMonth = now.getMonth()
158-
return lastResetMonth !== currentMonth ||
159-
(now.getFullYear() > lastResetAt.getFullYear())
160-
case ResetPeriod.NONE:
161-
default:
162-
return false
163-
}
164-
}
165-
```
166-
167-
#### 3.2 Credit Reset Logic
168-
169-
```typescript
170-
static async checkAndResetCredits(
171-
existingCredits: ChatUsageCredits,
172-
chatbotId: string
173-
): Promise<ChatUsageCredits> {
174-
const chatbot = await prisma.chatbot.findUnique({
175-
where: { id: chatbotId },
176-
select: { creditSettings: true }
177-
})
76+
#### 3.1 Reset Period Calculations (current)
17877

179-
const settings = chatbot?.creditSettings as CreditSettings | null
180-
if (!settings || settings.resetPeriod === 'none') {
181-
return existingCredits
182-
}
78+
Implemented in `apps/chat/src/utils/creditPeriods.ts` with fixed period alignment.
18379

184-
const shouldReset = this.shouldResetCredits(
185-
existingCredits.lastResetAt || existingCredits.createdAt,
186-
settings.resetPeriod as ResetPeriod
187-
)
188-
189-
if (shouldReset) {
190-
return await prisma.chatUsageCredits.update({
191-
where: { id: existingCredits.id },
192-
data: {
193-
current: Math.min(
194-
existingCredits.current.toNumber() + settings.resetAmount,
195-
settings.maxCredits
196-
),
197-
total: settings.maxCredits,
198-
lastResetAt: new Date(),
199-
resetCount: existingCredits.resetCount + 1
200-
}
201-
})
202-
}
80+
#### 3.2 Credit Reset Logic (current)
20381

204-
return existingCredits
205-
}
206-
```
82+
Handled inside `atomicResetCreditsIfNeeded` using fixed-period checks.
20783

20884
### Phase 4: API Updates
20985

@@ -232,16 +108,19 @@ export async function GET(
232108

233109
const chatbot = await prisma.chatbot.findUnique({
234110
where: { id: chatbotId },
235-
select: { creditSettings: true },
111+
select: {
112+
creditResetPeriod: true,
113+
creditInitialCredits: true,
114+
creditResetAmount: true,
115+
creditMaxCredits: true,
116+
},
236117
})
237118

238-
const settings = chatbot?.creditSettings as CreditSettings | null
239-
240119
return NextResponse.json({
241-
resetPeriod: settings?.resetPeriod || 'none',
242-
initialCredits: settings?.initialCredits || 10,
243-
resetAmount: settings?.resetAmount || 10,
244-
maxCredits: settings?.maxCredits || 10,
120+
resetPeriod: chatbot?.creditResetPeriod ?? 'none',
121+
initialCredits: chatbot?.creditInitialCredits ?? 0,
122+
resetAmount: chatbot?.creditResetAmount ?? 0,
123+
maxCredits: chatbot?.creditMaxCredits ?? 0,
245124
})
246125
}
247126
```
@@ -282,26 +161,7 @@ interface SettingsState {
282161
283162
### Phase 6: Migration Strategy
284163
285-
#### 6.1 Database Migration
286-
287-
```sql
288-
-- Add creditSettings to existing chatbots with defaults
289-
UPDATE "Chatbot"
290-
SET "creditSettings" = '{"initialCredits": 10, "resetPeriod": "weekly", "resetAmount": 10, "maxCredits": 10}'
291-
WHERE "creditSettings" IS NULL;
292-
293-
-- Add tracking fields to existing credit records
294-
ALTER TABLE "ChatUsageCredits"
295-
ADD COLUMN "periodStartedAt" TIMESTAMP,
296-
ADD COLUMN "lastResetAt" TIMESTAMP,
297-
ADD COLUMN "resetCount" INTEGER DEFAULT 0;
298-
299-
-- Initialize tracking for existing records
300-
UPDATE "ChatUsageCredits"
301-
SET "periodStartedAt" = "createdAt",
302-
"lastResetAt" = "createdAt"
303-
WHERE "periodStartedAt" IS NULL;
304-
```
164+
No additional migration is required for credit configuration; the scalar credit fields already exist on `Chatbot`, and the credit tracking fields are present on `ChatUsageCredits`.
305165
306166
#### 6.2 Existing User Credits
307167
@@ -315,23 +175,8 @@ Options for users with 0 credits:
315175
316176
#### 7.1 Common Credit Policies
317177
318-
```json
319-
// Conservative daily allowance
320-
{
321-
"initialCredits": 5,
322-
"resetPeriod": "daily",
323-
"resetAmount": 5,
324-
"maxCredits": 5
325-
}
326-
327-
// Weekly batch with accumulation
328-
{
329-
"initialCredits": 20,
330-
"resetPeriod": "weekly",
331-
"resetAmount": 15,
332-
"maxCredits": 30
333-
}
334-
178+
- Conservative daily allowance: `creditInitialCredits=5`, `creditResetPeriod=daily`, `creditResetAmount=5`, `creditMaxCredits=5`
179+
- Weekly batch with accumulation: `creditInitialCredits=20`, `creditResetPeriod=weekly`, `creditResetAmount=15`, `creditMaxCredits=30`
335180
// Monthly research allowance
336181
{
337182
"initialCredits": 100,

project/plans_archive/PLAN-chatbot-disclaimer.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,27 @@
44

55
This plan outlines the implementation of a comprehensive disclaimer system for KlickerUZH chatbots. The system ensures students understand AI limitations, data protection requirements, and usage responsibilities before accessing chatbot functionality. It introduces server-side, versioned consent tracking that is enforced by the chat APIs, while providing flexibility for different courses and departments.
66

7+
## Progress (feat/chat-gpt-5-1)
8+
9+
**Done on this branch**
10+
- Implemented disclaimer read + accept/decline endpoints (`/api/chatbots/[chatbotId]/disclaimer`) with acceptance tracked in `ChatUsageCredits`.
11+
- Enforced disclaimer acceptance in the main chat send endpoint (blocks usage when required + not accepted).
12+
13+
**Remaining**
14+
- Enforce disclaimer guard consistently across other endpoints (threads/messages/credits) and return `428 Precondition Required` with remediation info as per this plan.
15+
- With course↔chatbot many-to-many, decide whether disclaimers are per chatbot or per course↔chatbot link (and migrate storage accordingly if per-course).
16+
- Implement template/versioning/publishing workflow.
17+
718
## Problem Statement
819

920
### Current State
1021
- Students can immediately access chatbot functionality without understanding limitations
1122
- No mechanism to inform users about data protection and AI accuracy concerns
1223
- Lecturers cannot customize introductory content for their specific course context
13-
- No way to track informed consent for chatbot usage
14-
- A prototype disclaimer dialog exists client-side only (local storage/cookies) and is not enforced or persisted server-side; there is no version awareness
24+
- Disclaimer data model exists (`ChatbotDisclaimer`) with chatbot-level assignment
25+
- Acceptance tracked server-side in `ChatUsageCredits` (`acceptedDisclaimerId`, `disclaimerDeclined`)
26+
- `/api/chatbots/[chatbotId]/disclaimer` GET/POST endpoints exist and the chat endpoint blocks when acceptance is required and missing
27+
- Acceptance is per (participantId, chatbotId) and shared across courses
1528

1629
### Risks Without Disclaimer System
1730
- Students may over-rely on AI-generated content without understanding limitations

project/plans_archive/PLAN-chatbot-enhancements.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ This document outlines the implementation plan for enhancing the chat applicatio
99
3. **Tool filtering per mode** - Control which tools from each MCP server are available based on the chat mode (tutor, explainer, etc.)
1010
4. **Priority-based MCP loading** - Define the order in which MCP servers are loaded and how tool conflicts are resolved
1111

12+
## Compatibility with Course↔Chatbot N:N
13+
14+
- MCP configuration remains chatbot-scoped; access/routing will move to course-scoped endpoints once a link table exists.
15+
- If course-scoped contexts are introduced, consider whether MCP calls should include course context (header or tool metadata) in addition to chatbot ID.
16+
17+
## Progress (feat/chat-gpt-5-1)
18+
19+
**Done on this branch**
20+
- Updated GPT-5.1 Azure integration to use the Azure Responses API (`/openai/v1/responses`) with `api-version=preview` for reliable streaming.
21+
22+
**Remaining**
23+
- If we move to course-scoped chat context with course↔chatbot many-to-many, consider passing course context to MCP calls and/or supporting per-course overrides for MCP configuration.
24+
1225
## Architecture Goals
1326

1427
- **Relational design** - Use dedicated tables for MCP servers with proper relationships

project/plans_wip/PLAN-chat-assistant-ui-upgrade-v0.11.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@
44

55
Upgrade `@assistant-ui/*` packages in `apps/chat` to the latest `0.11.x` series (from `0.10.x`) to pick up upstream fixes/features, while keeping the current “external store runtime” architecture.
66

7+
## Progress (feat/chat-gpt-5-1)
8+
9+
**Done on this branch**
10+
- Preserved extra per-message fields by mapping them into `metadata.custom` in `RuntimeProvider.tsx`.
11+
- Implemented URL-based thread navigation while retaining the external-store runtime approach.
12+
13+
**Remaining**
14+
- Upgrade `@assistant-ui/*` to v0.11.x and fix breaking changes; verify tool fallback + markdown rendering.
15+
- Re-verify that `metadata.custom` mapping survives the upgrade.
16+
717
## Current state (code)
818

919
- `apps/chat/package.json`:

0 commit comments

Comments
 (0)