feat: implement DCL ADIF parser and service integration
- Add shared ADIF parser utility (src/backend/utils/adif-parser.js) - parseADIF(): Parse ADIF format into QSO records - parseDCLResponse(): Parse DCL's JSON response format - normalizeBand() and normalizeMode(): Standardize band/mode names - Implement DCL service (src/backend/services/dcl.service.js) - fetchQSOsFromDCL(): Fetch from DCL API (ready for API availability) - parseDCLJSONResponse(): Parse example payload format - syncQSOs(): Update existing QSOs with DCL confirmations - Support DCL-specific fields: DCL_QSL_RCVD, DCL_QSLRDATE, DARC_DOK, MY_DARC_DOK - Refactor LoTW service to use shared ADIF parser - Remove duplicate parseADIF, normalizeBand, normalizeMode functions - Import from shared utility for consistency - Tested with example DCL payload - Successfully parses all 6 QSOs - Correctly extracts DCL confirmation data - Handles ADIF format with <EOR> delimiters Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
123
CLAUDE.md
123
CLAUDE.md
@@ -104,3 +104,126 @@ bun --hot ./index.ts
|
||||
```
|
||||
|
||||
For more information, read the Bun API docs in `node_modules/bun-types/docs/**.mdx`.
|
||||
|
||||
## Project: Quickawards by DJ7NT
|
||||
|
||||
Quickawards is a amateur radio award tracking application that calculates progress toward various awards based on QSO (contact) data.
|
||||
|
||||
### Award System Architecture
|
||||
|
||||
The award system is JSON-driven and located in `award-definitions/` directory. Each award has:
|
||||
- `id`: Unique identifier (e.g., "dld", "dxcc")
|
||||
- `name`: Display name
|
||||
- `description`: Short description
|
||||
- `caption`: Detailed explanation
|
||||
- `category`: Award category ("dxcc", "darc", etc.)
|
||||
- `rules`: Award calculation logic
|
||||
|
||||
### Award Rule Types
|
||||
|
||||
1. **`entity`**: Count unique entities (DXCC countries, states, grid squares)
|
||||
- `entityType`: What to count ("dxcc", "state", "grid", "callsign")
|
||||
- `target`: Number required for award
|
||||
- `filters`: Optional filters (band, mode, etc.)
|
||||
- `displayField`: Optional field to display
|
||||
|
||||
2. **`dok`**: Count unique DOK (DARC Ortsverband Kennung) combinations
|
||||
- `target`: Number required
|
||||
- `confirmationType`: "dcl" (DARC Community Logbook)
|
||||
- Counts unique (DOK, band, mode) combinations
|
||||
- Only DCL-confirmed QSOs count
|
||||
|
||||
3. **`points`**: Point-based awards
|
||||
- `stations`: Array of {callsign, points}
|
||||
- `target`: Points required
|
||||
- `countMode`: "perStation", "perBandMode", or "perQso"
|
||||
|
||||
4. **`filtered`**: Filtered version of another award
|
||||
- `baseRule`: The base entity rule
|
||||
- `filters`: Additional filters to apply
|
||||
|
||||
5. **`counter`**: Count QSOs or callsigns
|
||||
|
||||
### Key Files
|
||||
|
||||
**Backend Award Service**: `src/backend/services/awards.service.js`
|
||||
- `getAllAwards()`: Returns all available award definitions
|
||||
- `calculateAwardProgress(userId, award, options)`: Main calculation function
|
||||
- `calculateDOKAwardProgress(userId, award, options)`: DOK-specific calculation
|
||||
- `calculatePointsAwardProgress(userId, award, options)`: Point-based calculation
|
||||
- `getAwardEntityBreakdown(userId, awardId)`: Detailed entity breakdown
|
||||
- `getAwardProgressDetails(userId, awardId)`: Progress with details
|
||||
|
||||
**Database Schema**: `src/backend/db/schema/index.js`
|
||||
- QSO fields include: `darcDok`, `dclQslRstatus`, `dclQslRdate`
|
||||
- DOK fields support DLD award tracking
|
||||
- DCL confirmation fields separate from LoTW
|
||||
|
||||
**Award Definitions**: `award-definitions/*.json`
|
||||
- Add new awards by creating JSON definition files
|
||||
- Add filename to `loadAwardDefinitions()` file list in awards.service.js
|
||||
|
||||
### DLD Award Implementation (COMPLETED)
|
||||
|
||||
The DLD (Deutschland Diplom) award was recently implemented:
|
||||
|
||||
**Definition**: `award-definitions/dld.json`
|
||||
```json
|
||||
{
|
||||
"id": "dld",
|
||||
"name": "DLD",
|
||||
"description": "Deutschland Diplom - Confirm 100 unique DOKs on different bands/modes",
|
||||
"caption": "Contact and confirm stations with 100 unique DOKs (DARC Ortsverband Kennung) on different band/mode combinations.",
|
||||
"category": "darc",
|
||||
"rules": {
|
||||
"type": "dok",
|
||||
"target": 100,
|
||||
"confirmationType": "dcl",
|
||||
"displayField": "darcDok"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation Details**:
|
||||
- Function: `calculateDOKAwardProgress()` in `src/backend/services/awards.service.js` (lines 173-268)
|
||||
- Counts unique (DOK, band, mode) combinations
|
||||
- Only DCL-confirmed QSOs count (`dclQslRstatus === 'Y'`)
|
||||
- Each unique DOK on each unique band/mode counts separately
|
||||
- Returns worked, confirmed counts and entity breakdowns
|
||||
|
||||
**Database Fields Used**:
|
||||
- `darcDok`: DOK identifier (e.g., "F03", "P30", "G20")
|
||||
- `band`: Band (e.g., "80m", "40m", "20m")
|
||||
- `mode`: Mode (e.g., "CW", "SSB", "FT8")
|
||||
- `dclQslRstatus`: DCL confirmation status ('Y' = confirmed)
|
||||
- `dclQslRdate`: DCL confirmation date
|
||||
|
||||
**Documentation**: See `docs/DOCUMENTATION.md` for complete documentation including DLD award example.
|
||||
|
||||
### Adding New Awards
|
||||
|
||||
To add a new award:
|
||||
|
||||
1. Create JSON definition in `award-definitions/`
|
||||
2. Add filename to `loadAwardDefinitions()` in `src/backend/services/awards.service.js`
|
||||
3. If new rule type needed, add calculation function
|
||||
4. Add type handling in `calculateAwardProgress()` switch statement
|
||||
5. Add type handling in `getAwardEntityBreakdown()` if needed
|
||||
6. Update documentation in `docs/DOCUMENTATION.md`
|
||||
7. Test with sample QSO data
|
||||
|
||||
### Confirmation Systems
|
||||
|
||||
- **LoTW (Logbook of The World)**: ARRL's confirmation system
|
||||
- Fields: `lotwQslRstatus`, `lotwQslRdate`
|
||||
- Used for DXCC, WAS, VUCC, most awards
|
||||
|
||||
- **DCL (DARC Community Logbook)**: DARC's confirmation system
|
||||
- Fields: `dclQslRstatus`, `dclQslRdate`
|
||||
- Required for DLD award
|
||||
- German amateur radio specific
|
||||
|
||||
### Recent Commits
|
||||
|
||||
- `c982dcd`: feat: implement DLD (Deutschland Diplom) award
|
||||
- `322ccaf`: docs: add DLD (Deutschland Diplom) award documentation
|
||||
|
||||
Reference in New Issue
Block a user