Skip to content

Commit 52dccb1

Browse files
feat: newm-admin Earnings dashboard
1 parent 2ac2bef commit 52dccb1

25 files changed

Lines changed: 2783 additions & 77 deletions

.agent/system/api-endpoints.md

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Authorization: Bearer <jwt_token>
3232
| **Users** | `/v1/users` | User profile management |
3333
| **Songs** | `/v1/songs` | Song metadata and management |
3434
| **Earnings** | `/v1/earnings` | Artist earnings |
35+
| **Earnings (Admin)** | `/v1/earnings/admin` | Admin earnings management |
3536
| **Distribution** | `/v1/distribution` | DSP distribution |
3637
| **Cardano** | `/v1/cardano` | Wallet and blockchain operations |
3738
| **Collaborations** | `/v1/collaborations` | Artist collaborations |
@@ -104,11 +105,59 @@ Delete a song.
104105

105106
### Earnings
106107

107-
#### GET `/v1/earnings`
108-
List earnings for current user.
108+
#### GET `/v1/earnings/{walletAddress}`
109+
Get earnings for a wallet address (requires recaptcha verification).
109110

110-
#### POST `/v1/earnings/{id}/claim`
111-
Claim earnings to wallet.
111+
#### GET `/v1/earnings/song/{songId}`
112+
Get earnings by song ID with optional date range filters.
113+
114+
**Query Parameters:**
115+
| Param | Type | Description |
116+
|-------|------|-------------|
117+
| `startDate` | datetime | Filter earnings from this date |
118+
| `endDate` | datetime | Filter earnings until this date |
119+
120+
#### POST `/v1/earnings`
121+
Create a claim order for all unclaimed earnings on a wallet.
122+
123+
### Earnings (Admin)
124+
125+
> **Auth:** Requires `AUTH_JWT_ADMIN` (admin-only endpoints)
126+
127+
#### GET `/v1/earnings/admin`
128+
Fetch all earnings records.
129+
130+
#### POST `/v1/earnings/admin`
131+
Batch create earnings records.
132+
133+
**Request:** `List<Earning>`
134+
135+
#### DELETE `/v1/earnings/admin`
136+
Delete earnings by IDs.
137+
138+
**Request:**
139+
```json
140+
["uuid1", "uuid2", "uuid3"]
141+
```
142+
143+
**Response:** `204 No Content`
144+
145+
#### GET `/v1/earnings/admin/{songIdOrIsrc}`
146+
Get earnings by song ID or ISRC.
147+
148+
**Path Parameters:**
149+
- `songIdOrIsrc` — UUID or ISRC format (e.g., `IE-LOI-23-01693`)
150+
151+
#### POST `/v1/earnings/admin/{songIdOrIsrc}`
152+
Create royalty splits for a song.
153+
154+
**Request:**
155+
```json
156+
{
157+
"usdAmount": 10500000
158+
}
159+
```
160+
> Amount is in 6-decimal format (10.50 USD = 10500000)
112161
113162
---
114163

.agent/task/admin/newm-admin.md

Lines changed: 183 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,173 @@ graph LR
7676

7777
**Priority:** High
7878

79+
#### API Endpoints
80+
81+
The admin app uses JWT-protected admin endpoints from the backend:
82+
83+
| Endpoint | Method | Purpose |
84+
|----------|--------|---------|
85+
| `/v1/earnings/admin` | GET | Fetch all earnings records |
86+
| `/v1/earnings/admin` | POST | Batch create earnings (accepts `List<Earning>`) |
87+
| `/v1/earnings/admin` | DELETE | Delete earnings by IDs (accepts `List<UUID>`) |
88+
| `/v1/earnings/admin/{songIdOrIsrc}` | GET | Get earnings by song ID or ISRC |
89+
| `/v1/earnings/admin/{songIdOrIsrc}` | POST | Create royalty splits for a song |
90+
91+
**Earning Model Fields:**
92+
- `id` (UUID), `songId` (UUID), `stakeAddress`, `amount` (Long, 6 decimals)
93+
- `memo`, `startDate`, `endDate`, `claimed`, `claimedAt`, `claimOrderId`
94+
- `createdAt`, `nftPolicyId`, `nftAssetName`
95+
96+
**AddSongRoyaltyRequest:** Either `newmAmount` or `usdAmount` (BigInteger, 6 decimals)
97+
98+
---
99+
100+
#### UI Components
101+
102+
##### Summary Boxes
103+
104+
Three summary cards at the top of the Earnings dashboard, calculated from the filtered data:
105+
106+
| Box | Description | Calculation |
107+
|-----|-------------|-------------|
108+
| **Total Earnings** | Sum of all earnings in current filter | `Σ earning.amount` |
109+
| **Claimed Earnings** | Sum of claimed earnings | `Σ earning.amount WHERE claimed == true` |
110+
| **Unclaimed Earnings** | Sum of unclaimed earnings | `Total - Claimed` |
111+
112+
> [!NOTE]
113+
> All amounts display in NEWM tokens with 6 decimal places, prefixed with `Ɲ` symbol (e.g., `Ɲ 1,234.567890`).
114+
115+
##### Earnings Table
116+
117+
A sortable, filterable table displaying all earnings:
118+
119+
| Column | Sortable | Filterable | Notes |
120+
|--------|----------|------------|-------|
121+
| ID ||| UUID |
122+
| Song ID ||| UUID or display song title if available |
123+
| Stake Address ||| Cardano stake address |
124+
| Amount ||| Display as `Ɲ X.XXXXXX` |
125+
| Memo ||| Freeform text |
126+
| Claimed ||| Boolean (checkbox filter) |
127+
| Claimed At ||| DateTime, null if unclaimed |
128+
| Created At ||| DateTime (supports date range filter) |
129+
130+
**Table Features:**
131+
- **Refresh Button:** Fetches latest data from server
132+
- **Date Range Filter:** Filter by `createdAt` date range (critical requirement)
133+
- **Infinite Scroll:** Virtual list handles large datasets efficiently
134+
135+
##### Toast Notification System
136+
137+
A toast notification system to inform users of API operation results:
138+
139+
| Toast Type | Behavior | Auto-Dismiss |
140+
|------------|----------|--------------|
141+
| **Success** | Green background, checkmark icon | 5 seconds |
142+
| **Warning** | Yellow/orange background, warning icon | Manual X close required |
143+
| **Error** | Red background, error icon | Manual X close required |
144+
145+
Toast content should include:
146+
- Clear message describing success or failure
147+
- For failures: Include error message from API response
148+
- Position: Top-right corner of the work area, stacked if multiple
149+
150+
---
151+
152+
#### Workflows
153+
154+
##### Add Earnings (Single Song)
155+
156+
**Button:** "Add Earnings" in the toolbar
157+
158+
**Dialog Fields:**
159+
| Field | Type | Description |
160+
|-------|------|-------------|
161+
| Song ID or ISRC | Text input | Accepts UUID or ISRC format (e.g., `IE-LOI-23-01693`) |
162+
| Amount (USD) | Decimal input | User enters USD value (e.g., `10.50`) |
163+
164+
**Process:**
165+
1. User enters songId/ISRC and USD amount
166+
2. Convert amount to 6-decimal integer: `10.50``10500000`
167+
3. Call `POST /v1/earnings/admin/{songIdOrIsrc}` with `{ usdAmount: 10500000 }`
168+
4. On success: Show success toast, refresh table
169+
5. On failure: Show error toast with API error message
170+
171+
##### Upload Earnings CSV
172+
173+
**Button:** "Upload CSV" in the toolbar
174+
175+
**CSV Format (Input):**
176+
```csv
177+
songId_or_isrc,amount_usd
178+
550e8400-e29b-41d4-a716-446655440000,10.50
179+
IE-LOI-23-01693,25.00
180+
```
181+
182+
**Process:**
183+
1. User selects CSV file via native file picker
184+
2. Parse CSV, validate format (2 columns required)
185+
3. For each row:
186+
- Convert USD to 6-decimal integer
187+
- Call `POST /v1/earnings/admin/{songIdOrIsrc}`
188+
- Record result (success or error message)
189+
4. Modify CSV to add result column
190+
5. Save modified CSV with results
191+
192+
**CSV Format (Output):**
193+
```csv
194+
songId_or_isrc,amount_usd,result
195+
550e8400-e29b-41d4-a716-446655440000,10.50,Success
196+
IE-LOI-23-01693,25.00,Error: No song found with ISRC: IE-LOI-23-01693
197+
```
198+
199+
6. Show summary toast: "Processed X records: Y succeeded, Z failed"
200+
7. If any failures: Show warning toast prompting user to check output file
201+
202+
##### Delete Earnings (Multi-Select)
203+
204+
**Button:** "Delete Selected" in the toolbar (disabled when no rows selected)
205+
206+
**UI Requirements:**
207+
| Element | Description |
208+
|---------|-------------|
209+
| Checkbox column | Leftmost column with checkbox for each row |
210+
| Select All | Header checkbox to select/deselect all filtered rows. Shows indeterminate (minus icon) when some rows selected, check when all selected |
211+
| Delete Button | Enabled only when 1+ rows selected, shows count |
212+
| Confirmation | Modal dialog before deletion |
213+
214+
**Process:**
215+
1. User selects one or more rows via checkboxes
216+
2. "Delete Selected (N)" button becomes enabled
217+
3. User clicks delete button
218+
4. Confirmation dialog: "Delete N earnings records? This cannot be undone."
219+
5. On confirm: Call `DELETE /v1/earnings/admin` with list of earning IDs
220+
6. On success: Refresh table, show success toast
221+
7. On failure: Show error toast with API error message
222+
223+
**API Endpoint:**
224+
- `DELETE /v1/earnings/admin` - Admin-only endpoint
225+
- Request body: `["uuid1", "uuid2", ...]`
226+
- Response: `204 No Content` on success
227+
228+
---
229+
230+
#### Implementation Status
231+
79232
| Requirement | Status |
80233
|-------------|--------|
81-
| List all earnings with pagination | ⬜ Not started |
82-
| Filter by artist, song, date range | ⬜ Not started |
83-
| View earnings details | ⬜ Not started |
84-
| Export earnings data | ⬜ Not started |
234+
| List all earnings with sortable, scrollable table | ✅ Completed |
235+
| Filter by date range | ✅ Completed |
236+
| Filter by stake address, song, memo | ✅ Completed |
237+
| Summary boxes (Total/Claimed/Unclaimed) | ✅ Completed |
238+
| NEWM token display with Ɲ symbol | ✅ Completed |
239+
| Refresh button | ✅ Completed |
240+
| Toast notification system | ✅ Completed |
241+
| Add Earnings dialog | ✅ Completed |
242+
| Upload CSV workflow | ✅ Completed |
243+
| CSV result export | ✅ Completed |
244+
| Delete earnings (multi-select) | ✅ Completed |
245+
| Select All header checkbox (with indeterminate state) | ✅ Completed |
85246

86247
### 🔲 Refunds Processing
87248

@@ -152,11 +313,14 @@ cd newm-admin && cargo build
152313
# Run (development)
153314
cd newm-admin && cargo run
154315

316+
# Check for Format issues
317+
cd newm-admin && cd newm-admin && cargo fmt --all -- --check
318+
155319
# Format code
156-
cd newm-admin && cargo fmt
320+
cd newm-admin && cd newm-admin && cargo fmt --all
157321

158322
# Lint
159-
cd newm-admin && cargo clippy
323+
cd newm-admin && cargo clippy --all-targets --all-features -- -D warnings
160324
```
161325

162326
---
@@ -165,24 +329,30 @@ cd newm-admin && cargo clippy
165329

166330
The admin app communicates with the NEWM backend:
167331

168-
| Endpoint | Purpose |
169-
|----------|---------|
170-
| `POST /v1/auth/login` | Admin authentication |
171-
| `GET /v1/auth/refresh` | Token refresh |
172-
| `GET /v1/earnings/*` | Earnings data (planned) |
173-
| `POST /v1/refunds/*` | Refund operations (planned) |
332+
| Endpoint | Method | Purpose |
333+
|----------|--------|---------|
334+
| `POST /v1/auth/login` | POST | Admin authentication |
335+
| `GET /v1/auth/refresh` | GET | Token refresh |
336+
| `GET /v1/earnings/admin` | GET | Fetch all earnings |
337+
| `POST /v1/earnings/admin` | POST | Batch create earnings |
338+
| `DELETE /v1/earnings/admin` | DELETE | Delete earnings by IDs |
339+
| `GET /v1/earnings/admin/{songIdOrIsrc}` | GET | Get earnings by song/ISRC |
340+
| `POST /v1/earnings/admin/{songIdOrIsrc}` | POST | Create royalty splits |
341+
| `POST /v1/refunds/*` | POST | Refund operations (planned) |
174342

175343
---
176344

177345
## Change Log
178346

179347
| Date | Feature | Description |
180348
|------|---------|-------------|
349+
| 2026-01-09 | Select All | Header checkbox with indeterminate state for bulk selection |
350+
| 2026-01-08 | Earnings Table | Full-featured earnings table with filtering, sorting, date range, summary stats, copy-to-clipboard |
181351
| 2026-01-07 | Dashboard | Added sidebar nav with Earnings/Refunds, work area panels |
182352
| 2026-01-07 | Auth | JWT admin validation, login view with environment selector |
183353
| 2026-01-06 | Init | Project setup with GPUI, basic login UI |
184354

185355
---
186356

187357
**Status:** 🚧 In Progress
188-
**Last Updated:** 2026-01-08
358+
**Last Updated:** 2026-01-09

.agent/workflows/admin.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,24 @@ cd newm-admin && cargo run
5656
cd newm-admin && cargo build --release
5757
```
5858

59+
### Format Code Check
60+
// turbo
61+
```bash
62+
cd newm-admin && cargo fmt --all -- --check
63+
```
64+
5965
### Format Code
6066

6167
// turbo
6268
```bash
63-
cd newm-admin && cargo fmt
69+
cd newm-admin && cargo fmt --all
6470
```
6571

6672
### Lint
6773

6874
// turbo
6975
```bash
70-
cd newm-admin && cargo clippy
76+
cd newm-admin && cargo clippy --all-targets --all-features -- -D warnings
7177
```
7278

7379
---
@@ -206,4 +212,4 @@ When visual verification of UI changes is needed:
206212
4. Document what specific UI elements should be visible in the screenshot
207213

208214
Example prompt to user:
209-
> "Please run the application and take a screenshot of [specific view]. I need to verify that [specific UI element] appears correctly. Attach the screenshot to your reply."
215+
> "Please run the application and take a screenshot of [specific view]. I need to verify that [specific UI element] appears correctly. Attach the screenshot to your reply."

0 commit comments

Comments
 (0)