Skip to content

Commit fc137a6

Browse files
committed
fix: activity timestamp
Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
1 parent b3c3880 commit fc137a6

2 files changed

Lines changed: 23 additions & 4 deletions

File tree

  • .claude/skills/scaffold-snowflake-connector
  • services/apps/snowflake_connectors/src/integrations/meetings/meeting-attendance

.claude/skills/scaffold-snowflake-connector/SKILL.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ After Step 1 and/or Step 2, build a column registry per table:
196196

197197
**Store this as the canonical column reference. Every column name used in generated code must appear in this registry. Never assume or invent a column name.**
198198

199+
**Flag non-VARCHAR column types** (e.g., `DATE`, `TIME`, `TIMESTAMP_TZ`, `BOOLEAN`, `NUMBER`) — these arrive as native JS types from the Parquet reader, not strings (see touch point 9 rules).
200+
199201
For each JOIN table, check whether any existing transformer in `services/apps/snowflake_connectors/src/integrations/` queries from the same table. If yes, inherit its column mappings; if no, treat every column as unknown and derive it from sample data in the Pre-Analysis step below.
200202

201203
### Step 3 — Sample data
@@ -568,6 +570,7 @@ File: `services/apps/snowflake_connectors/src/integrations/{platform}/{source}/b
568570
**Rules (enforced — do not deviate):**
569571
- Use explicit column names only. Do not use `table.*` or `table.* EXCLUDE (...)` in new implementations — existing sources (TNC, CVENT) use these patterns but new sources should list columns explicitly to avoid parquet encoding/decoding issues
570572
- If any TIMESTAMP_TZ columns exist in the schema, exclude and re-cast them as TIMESTAMP_NTZ (see CVENT pattern)
573+
- Do not concatenate or transform date/time columns in SQL — keep them as separate columns and let the transformer handle type coercion (see touch point 9 rules)
571574
- Follow the CTE structure:
572575
1. `org_accounts` CTE (if org data present)
573576
2. `CDP_MATCHED_SEGMENTS` CTE (always)
@@ -588,6 +591,8 @@ Show the full generated file and ask for confirmation before writing.
588591
File: `services/apps/snowflake_connectors/src/integrations/{platform}/{source}/transformer.ts`
589592

590593
**Rules (enforced — do not deviate):**
594+
595+
- **Parquet type coercion — never blindly cast `row.COLUMN as string`.** Snowflake types may arrive as native JS types after Parquet decoding (e.g., `DATE``Date` object, `TIME``number` in ms, `BOOLEAN``boolean`). Always check the Snowflake column type from the schema registry and handle the actual JS type the Parquet reader delivers — do not assume every column is a string.
591596
- All string comparisons must be case-insensitive: use `.toLowerCase()` on both sides of comparison only; preserve the original value in the output
592597
- No broad `else` statements — every branch must have an explicit condition
593598
- All column names referenced in code must exactly match the schema registry — never assumed

services/apps/snowflake_connectors/src/integrations/meetings/meeting-attendance/transformer.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,23 @@ import { TransformedActivity, TransformerBase } from '../../../core/transformerB
1212

1313
const log = getServiceChildLogger('meetingAttendanceTransformer')
1414

15+
function toISOTimestamp(rawDate: unknown, rawTime: unknown): string | null {
16+
const date =
17+
rawDate instanceof Date
18+
? new Date(rawDate)
19+
: typeof rawDate === 'string'
20+
? new Date(rawDate)
21+
: null
22+
if (!date || isNaN(date.getTime())) return null
23+
if (typeof rawTime === 'number') {
24+
date.setTime(date.getTime() + rawTime)
25+
} else if (typeof rawTime === 'string' && rawTime.trim()) {
26+
const combined = new Date(`${date.toISOString().slice(0, 10)}T${rawTime.trim()}Z`)
27+
if (!isNaN(combined.getTime())) return combined.toISOString()
28+
}
29+
return date.toISOString()
30+
}
31+
1532
export class MeetingAttendanceTransformer extends TransformerBase {
1633
readonly platform = PlatformType.MEETINGS
1734

@@ -39,10 +56,7 @@ export class MeetingAttendanceTransformer extends TransformerBase {
3956
return null
4057
}
4158

42-
const meetingDate = (row.MEETING_DATE as string | null) || null
43-
const meetingTime = (row.MEETING_TIME as string | null) || null
44-
const timestamp =
45-
meetingDate && meetingTime ? `${meetingDate}T${meetingTime}` : meetingDate || null
59+
const timestamp = toISOTimestamp(row.MEETING_DATE, row.MEETING_TIME)
4660

4761
const primaryKey = (row.PRIMARY_KEY as string)?.trim()
4862

0 commit comments

Comments
 (0)