Skip to content

feat: Activity Logging System — Track All User Actions with Points #147

@LarytheLord

Description

@LarytheLord

What

Add an activity logging system that records every meaningful user action with point values. This is the foundation for analytics, engagement scoring, and retention tracking.

Why

We currently have zero visibility into what users actually do on the platform. We can't answer: how many quests were claimed this week? Who's active? Who's at risk of churning? Activity logs answer all of these.

Schema Addition

Add to `prisma/schema.prisma`:

```prisma
model ActivityLog {
id String @id @default(uuid()) @db.Uuid
userId String @Map("user_id") @db.Uuid
action String // e.g. "quest_apply", "quest_complete", "rank_up"
points Int @default(0)
metadata Json? // { questId, fromRank, toRank, etc. }
createdAt DateTime @default(now()) @Map("created_at") @db.Timestamptz

user User @relation(fields: [userId], references: [id], onDelete: Cascade)

@@index([userId])
@@index([action])
@@index([createdAt])
@@Map("activity_logs")
}
```

Add `activityLogs ActivityLog[]` relation to User model.

Activity Types & Points

```typescript
// lib/activity-points.ts
export const ACTIVITY_POINTS: Record<string, number> = {
quest_view: 1,
quest_apply: 10,
quest_start: 5,
quest_submit: 20,
quest_complete: 50,
quest_rework: 5,
rank_up: 100,
profile_update: 2,
party_create: 15,
party_join: 10,
streak_milestone: 25,
};
```

Utility: `lib/activity-logger.ts`

```typescript
export async function logActivity(
userId: string,
action: string,
metadata?: Record<string, unknown>,
db?: PrismaClient | Prisma.TransactionClient
) {
const client = db || prisma;
const points = ACTIVITY_POINTS[action] ?? 0;
await client.activityLog.create({
data: { userId, action, points, metadata: metadata ?? undefined },
});
}
```

Where to Call It

Add `logActivity()` calls in these existing files:

  • `app/api/quests/assignments/route.ts` POST → `logActivity(userId, 'quest_apply', { questId })`
  • `app/api/quests/submissions/route.ts` POST → `logActivity(userId, 'quest_submit', { questId })`
  • `lib/xp-utils.ts` after XP grant → `logActivity(userId, 'quest_complete', { questId, xp })`
  • `lib/xp-utils.ts` after rank up → `logActivity(userId, 'rank_up', { fromRank, toRank })`

API: `GET /api/admin/activity`

Admin-only endpoint returning:

  • Recent activity feed (paginated)
  • Daily active users (count distinct userId where createdAt > 24h ago)
  • Activity breakdown by type

Acceptance Criteria

  • ActivityLog model in schema, migration applied
  • `logActivity()` utility created
  • Activity logged on quest apply, submit, complete, and rank up
  • Admin API returns activity feed + DAU count
  • Type-check passes

Metadata

Metadata

Assignees

No one assigned

    Labels

    analyticsMetrics, dashboards, data trackingcontributor-friendlyWell-documented issue suitable for new contributorspriorityHigh priority for project goals

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions