@revos/cli 0.1.4 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -0
- package/README.md +104 -0
- package/dist/adapters/oclif/commands/action-runs/get.d.mts +6 -0
- package/dist/adapters/oclif/commands/action-runs/get.mjs +8 -0
- package/dist/adapters/oclif/commands/action-runs/list.d.mts +6 -0
- package/dist/adapters/oclif/commands/action-runs/list.mjs +8 -0
- package/dist/adapters/oclif/commands/actions/get-input-schema.d.mts +6 -0
- package/dist/adapters/oclif/commands/actions/get-input-schema.mjs +23 -0
- package/dist/adapters/oclif/commands/actions/get-params-schema.d.mts +6 -0
- package/dist/adapters/oclif/commands/actions/get-params-schema.mjs +23 -0
- package/dist/adapters/oclif/commands/actions/get.d.mts +6 -0
- package/dist/adapters/oclif/commands/actions/get.mjs +8 -0
- package/dist/adapters/oclif/commands/actions/list.d.mts +6 -0
- package/dist/adapters/oclif/commands/actions/list.mjs +27 -0
- package/dist/adapters/oclif/commands/ai-instructions/create.d.mts +6 -0
- package/dist/adapters/oclif/commands/ai-instructions/create.mjs +8 -0
- package/dist/adapters/oclif/commands/ai-instructions/delete.d.mts +6 -0
- package/dist/adapters/oclif/commands/ai-instructions/delete.mjs +8 -0
- package/dist/adapters/oclif/commands/ai-instructions/get.d.mts +6 -0
- package/dist/adapters/oclif/commands/ai-instructions/get.mjs +8 -0
- package/dist/adapters/oclif/commands/ai-instructions/list.d.mts +6 -0
- package/dist/adapters/oclif/commands/ai-instructions/list.mjs +8 -0
- package/dist/adapters/oclif/commands/ai-instructions/update.d.mts +6 -0
- package/dist/adapters/oclif/commands/ai-instructions/update.mjs +8 -0
- package/dist/adapters/oclif/commands/auth/login.d.mts +2 -2
- package/dist/adapters/oclif/commands/auth/login.mjs +2 -2
- package/dist/adapters/oclif/commands/auth/logout.d.mts +1 -1
- package/dist/adapters/oclif/commands/auth/logout.mjs +7 -3
- package/dist/adapters/oclif/commands/auth/status.d.mts +2 -2
- package/dist/adapters/oclif/commands/auth/status.mjs +2 -2
- package/dist/adapters/oclif/commands/gservice-account-keys/get.d.mts +6 -0
- package/dist/adapters/oclif/commands/gservice-account-keys/get.mjs +8 -0
- package/dist/adapters/oclif/commands/gservice-account-keys/reveal.d.mts +6 -0
- package/dist/adapters/oclif/commands/gservice-account-keys/reveal.mjs +14 -0
- package/dist/adapters/oclif/commands/gservice-accounts/create.d.mts +6 -0
- package/dist/adapters/oclif/commands/gservice-accounts/create.mjs +8 -0
- package/dist/adapters/oclif/commands/gservice-accounts/delete.d.mts +6 -0
- package/dist/adapters/oclif/commands/gservice-accounts/delete.mjs +8 -0
- package/dist/adapters/oclif/commands/gservice-accounts/get.d.mts +6 -0
- package/dist/adapters/oclif/commands/gservice-accounts/get.mjs +8 -0
- package/dist/adapters/oclif/commands/gservice-accounts/list.d.mts +6 -0
- package/dist/adapters/oclif/commands/gservice-accounts/list.mjs +8 -0
- package/dist/adapters/oclif/commands/init.d.mts +1 -1
- package/dist/adapters/oclif/commands/init.mjs +4 -3
- package/dist/adapters/oclif/commands/integrations/create.d.mts +11 -0
- package/dist/adapters/oclif/commands/integrations/create.mjs +16 -0
- package/dist/adapters/oclif/commands/integrations/get.d.mts +15 -0
- package/dist/adapters/oclif/commands/integrations/get.mjs +21 -0
- package/dist/adapters/oclif/commands/integrations/list.d.mts +11 -0
- package/dist/adapters/oclif/commands/integrations/list.mjs +16 -0
- package/dist/adapters/oclif/commands/integrations/update.d.mts +15 -0
- package/dist/adapters/oclif/commands/integrations/update.mjs +21 -0
- package/dist/adapters/oclif/commands/org/create.d.mts +6 -0
- package/dist/adapters/oclif/commands/org/create.mjs +8 -0
- package/dist/adapters/oclif/commands/org/current.d.mts +2 -2
- package/dist/adapters/oclif/commands/org/current.mjs +2 -2
- package/dist/adapters/oclif/commands/org/get.d.mts +6 -0
- package/dist/adapters/oclif/commands/org/get.mjs +8 -0
- package/dist/adapters/oclif/commands/org/list.d.mts +2 -2
- package/dist/adapters/oclif/commands/org/list.mjs +2 -2
- package/dist/adapters/oclif/commands/org/switch.d.mts +1 -1
- package/dist/adapters/oclif/commands/org/switch.mjs +5 -4
- package/dist/adapters/oclif/commands/overlays/diff.d.mts +2 -2
- package/dist/adapters/oclif/commands/overlays/diff.mjs +5 -5
- package/dist/adapters/oclif/commands/overlays/pull.d.mts +2 -2
- package/dist/adapters/oclif/commands/overlays/pull.mjs +4 -3
- package/dist/adapters/oclif/commands/overlays/push.d.mts +2 -2
- package/dist/adapters/oclif/commands/overlays/push.mjs +2 -2
- package/dist/adapters/oclif/commands/overlays/status.d.mts +2 -2
- package/dist/adapters/oclif/commands/overlays/status.mjs +2 -2
- package/dist/adapters/oclif/commands/score-groups/create.d.mts +6 -0
- package/dist/adapters/oclif/commands/score-groups/create.mjs +8 -0
- package/dist/adapters/oclif/commands/score-groups/delete.d.mts +6 -0
- package/dist/adapters/oclif/commands/score-groups/delete.mjs +8 -0
- package/dist/adapters/oclif/commands/score-groups/get.d.mts +6 -0
- package/dist/adapters/oclif/commands/score-groups/get.mjs +8 -0
- package/dist/adapters/oclif/commands/score-groups/list.d.mts +6 -0
- package/dist/adapters/oclif/commands/score-groups/list.mjs +8 -0
- package/dist/adapters/oclif/commands/score-groups/update.d.mts +6 -0
- package/dist/adapters/oclif/commands/score-groups/update.mjs +8 -0
- package/dist/adapters/oclif/commands/scores/create.d.mts +6 -0
- package/dist/adapters/oclif/commands/scores/create.mjs +8 -0
- package/dist/adapters/oclif/commands/scores/delete.d.mts +6 -0
- package/dist/adapters/oclif/commands/scores/delete.mjs +8 -0
- package/dist/adapters/oclif/commands/scores/list.d.mts +6 -0
- package/dist/adapters/oclif/commands/scores/list.mjs +8 -0
- package/dist/adapters/oclif/commands/scores/update.d.mts +6 -0
- package/dist/adapters/oclif/commands/scores/update.mjs +8 -0
- package/dist/adapters/oclif/commands/segments/create.d.mts +6 -0
- package/dist/adapters/oclif/commands/segments/create.mjs +8 -0
- package/dist/adapters/oclif/commands/segments/delete.d.mts +6 -0
- package/dist/adapters/oclif/commands/segments/delete.mjs +8 -0
- package/dist/adapters/oclif/commands/segments/evaluate.d.mts +6 -0
- package/dist/adapters/oclif/commands/segments/evaluate.mjs +14 -0
- package/dist/adapters/oclif/commands/segments/get-evaluation-history.d.mts +6 -0
- package/dist/adapters/oclif/commands/segments/get-evaluation-history.mjs +14 -0
- package/dist/adapters/oclif/commands/segments/get-version.d.mts +6 -0
- package/dist/adapters/oclif/commands/segments/get-version.mjs +23 -0
- package/dist/adapters/oclif/commands/segments/get.d.mts +6 -0
- package/dist/adapters/oclif/commands/segments/get.mjs +8 -0
- package/dist/adapters/oclif/commands/segments/list-versions.d.mts +6 -0
- package/dist/adapters/oclif/commands/segments/list-versions.mjs +29 -0
- package/dist/adapters/oclif/commands/segments/list.d.mts +6 -0
- package/dist/adapters/oclif/commands/segments/list.mjs +8 -0
- package/dist/adapters/oclif/commands/segments/restore-version.d.mts +6 -0
- package/dist/adapters/oclif/commands/segments/restore-version.mjs +23 -0
- package/dist/adapters/oclif/commands/segments/update.d.mts +6 -0
- package/dist/adapters/oclif/commands/segments/update.mjs +8 -0
- package/dist/adapters/oclif/commands/table-views/create.d.mts +6 -0
- package/dist/adapters/oclif/commands/table-views/create.mjs +8 -0
- package/dist/adapters/oclif/commands/table-views/delete.d.mts +6 -0
- package/dist/adapters/oclif/commands/table-views/delete.mjs +8 -0
- package/dist/adapters/oclif/commands/table-views/list.d.mts +6 -0
- package/dist/adapters/oclif/commands/table-views/list.mjs +8 -0
- package/dist/adapters/oclif/commands/table-views/update.d.mts +6 -0
- package/dist/adapters/oclif/commands/table-views/update.mjs +8 -0
- package/dist/adapters/oclif/commands/tables/create.d.mts +6 -0
- package/dist/adapters/oclif/commands/tables/create.mjs +8 -0
- package/dist/adapters/oclif/commands/tables/delete.d.mts +6 -0
- package/dist/adapters/oclif/commands/tables/delete.mjs +8 -0
- package/dist/adapters/oclif/commands/tables/get.d.mts +6 -0
- package/dist/adapters/oclif/commands/tables/get.mjs +8 -0
- package/dist/adapters/oclif/commands/tables/list.d.mts +6 -0
- package/dist/adapters/oclif/commands/tables/list.mjs +8 -0
- package/dist/adapters/oclif/commands/tables/update.d.mts +6 -0
- package/dist/adapters/oclif/commands/tables/update.mjs +8 -0
- package/dist/{base.command-DlVQ9Cqa.mjs → base.command-YiwlGlKs.mjs} +1 -1
- package/dist/{core-gKJ_V-K5.mjs → core-jpFPylBb.mjs} +31 -7
- package/dist/factory-BrFKT8t-.mjs +90 -0
- package/dist/{index-B8n2GxTc.d.mts → index-DD2Vr-pu.d.mts} +6 -3
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +2 -2
- package/dist/presets-D9b6IWKy.mjs +98 -0
- package/dist/templates/.devcontainer/devcontainer.json +2 -2
- package/dist/templates/AGENTS.md +19 -9
- package/dist/templates/skills/create-dbt-transformations/SKILL.md +21 -13
- package/dist/templates/skills/create-dbt-transformations/references/edge-cases.md +1 -1
- package/dist/templates/skills/create-semantic-model/SKILL.md +11 -11
- package/dist/templates/skills/create-semantic-model/references/cube-examples.md +83 -5
- package/dist/templates/skills/explore-lakehouse/SKILL.md +7 -3
- package/dist/templates/skills/load-sample-data/SKILL.md +119 -0
- package/package.json +8 -3
- /package/dist/{base.command-BjFWMIzL.d.mts → base.command-d7VW6WTp.d.mts} +0 -0
- /package/dist/{types-DmuJzN0Z.d.mts → types-C_p_6rkj.d.mts} +0 -0
- /package/dist/{types-DsQtGF-c.d.mts → types-Y_ht_ja5.d.mts} +0 -0
package/dist/templates/AGENTS.md
CHANGED
|
@@ -11,12 +11,22 @@ This is a RevOS data engineering project for **<%=orgName%>** organization.
|
|
|
11
11
|
|
|
12
12
|
## Key Commands
|
|
13
13
|
|
|
14
|
-
| Command
|
|
15
|
-
|
|
|
16
|
-
| `revos auth login`
|
|
17
|
-
| `revos overlays push`
|
|
18
|
-
| `revos overlays pull`
|
|
19
|
-
| `revos overlays diff`
|
|
20
|
-
| `
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
14
|
+
| Command | Description |
|
|
15
|
+
| -------------------------------- | ------------------------------------- |
|
|
16
|
+
| `revos auth login` | Authenticate with RevOS |
|
|
17
|
+
| `revos overlays push` | Push Cube overlays to RevOS |
|
|
18
|
+
| `revos overlays pull` | Pull Cube overlays from RevOS |
|
|
19
|
+
| `revos overlays diff` | Compare local vs remote overlays |
|
|
20
|
+
| `revos integrations list` | Open integrations page in RevOS UI |
|
|
21
|
+
| `revos integrations create` | Open RevOS UI to add a data source |
|
|
22
|
+
| `revos integrations update <id>` | Open RevOS UI to edit an integration |
|
|
23
|
+
| `dbt run` | Run dbt models |
|
|
24
|
+
| `dbt test` | Test dbt models |
|
|
25
|
+
| `bq ls` | List BigQuery datasets/tables |
|
|
26
|
+
|
|
27
|
+
## Data Sources
|
|
28
|
+
|
|
29
|
+
When the user wants to add or manage data sources (integrations):
|
|
30
|
+
- To add a new data source: suggest `revos integrations create`
|
|
31
|
+
- To view existing integrations: suggest `revos integrations list`
|
|
32
|
+
- If a BigQuery dataset is empty or has no tables, mention that integrations can be configured with `revos integrations create`, or sample data can be loaded if available
|
|
@@ -5,7 +5,7 @@ description: Create new dbt transformations (bronze/silver/gold models) in the R
|
|
|
5
5
|
|
|
6
6
|
# Create dbt Transformations
|
|
7
7
|
|
|
8
|
-
Use this skill to generate SQL models, declare sources, update `schema.yml`, and validate models with `
|
|
8
|
+
Use this skill to generate SQL models, declare sources, update `schema.yml`, and validate models with `dbt run` / `dbt test`.
|
|
9
9
|
|
|
10
10
|
For BigQuery exploration (listing datasets, inspecting raw tables, previewing rows, null rates), load the `explore-lakehouse` skill. If that skill is not installed, fall back to:
|
|
11
11
|
|
|
@@ -72,15 +72,13 @@ Always declare raw tables as sources before referencing them. Do not use bare fu
|
|
|
72
72
|
|
|
73
73
|
## Standard dbt Commands
|
|
74
74
|
|
|
75
|
-
Always use the `revos` wrapper:
|
|
76
|
-
|
|
77
75
|
```bash
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
76
|
+
dbt parse # validate syntax (no warehouse)
|
|
77
|
+
dbt compile --select <model> # resolve refs, produce compiled SQL
|
|
78
|
+
dbt run --select <model> # execute against warehouse
|
|
79
|
+
dbt test --select <model> # run tests
|
|
80
|
+
dbt build --select <model> # run + test
|
|
81
|
+
dbt build --select path:models/<layer> # entire layer
|
|
84
82
|
```
|
|
85
83
|
|
|
86
84
|
---
|
|
@@ -99,8 +97,8 @@ For each transformation (one at a time — do not batch):
|
|
|
99
97
|
6. Generate `dbt/models/<layer>/<model_name>.sql`.
|
|
100
98
|
7. Detect the primary key (Checkpoint 3 if ambiguous).
|
|
101
99
|
8. Add model entry to `dbt/models/<layer>/schema.yml` with PK and FK tests. See [schema-conventions.md](references/schema-conventions.md).
|
|
102
|
-
9. Run `
|
|
103
|
-
10. Run `
|
|
100
|
+
9. Run `dbt run --select <model_name>` and report result.
|
|
101
|
+
10. Run `dbt test --select <model_name>` and report result.
|
|
104
102
|
11. Summarize (see Final Response Format).
|
|
105
103
|
|
|
106
104
|
For multiple transformations in one request: repeat steps 1–11 per model in order.
|
|
@@ -169,6 +167,16 @@ If none produce a clear answer → Checkpoint 3.
|
|
|
169
167
|
|
|
170
168
|
A column is a FK candidate if it matches `<entity>_id` where `<entity>` ≠ model's own entity, is not part of the PK, and is not nullable by design. Add `not_null` test only (no `relationships` tests by default).
|
|
171
169
|
|
|
170
|
+
## Timestamp Column Propagation (Gold Models)
|
|
171
|
+
|
|
172
|
+
Every gold model **must** propagate at least one timestamp column so downstream Cube overlays can use SQL-based `refresh_key` (see `create-semantic-model` skill). Priority:
|
|
173
|
+
|
|
174
|
+
1. `_airbyte_extracted_at` — present on all Airbyte sources; always propagate if available in upstream.
|
|
175
|
+
2. `updated_at` / `modified_at` — CDC-friendly streams.
|
|
176
|
+
3. `created_at` — insert-only fact tables.
|
|
177
|
+
|
|
178
|
+
If the upstream source has none of these, document it in a SQL comment: `-- no timestamp column available from source`.
|
|
179
|
+
|
|
172
180
|
## SQL File Generation
|
|
173
181
|
|
|
174
182
|
See [sql-templates.md](references/sql-templates.md) for:
|
|
@@ -206,8 +214,8 @@ Tests:
|
|
|
206
214
|
- not_null on <fk>: added
|
|
207
215
|
|
|
208
216
|
Validation:
|
|
209
|
-
-
|
|
210
|
-
-
|
|
217
|
+
- dbt run: passed | failed
|
|
218
|
+
- dbt test: passed | failed
|
|
211
219
|
|
|
212
220
|
Physical table after run:
|
|
213
221
|
`<resolved_dataset>.<model_name>`
|
|
@@ -34,7 +34,7 @@ Declare it as a source in `dbt/models/bronze/schema.yml` first (see [schema-conv
|
|
|
34
34
|
|
|
35
35
|
1. Show the error verbatim — do not paraphrase warehouse errors.
|
|
36
36
|
2. Offer to fix the SQL based on the error message.
|
|
37
|
-
3. Do not proceed to `
|
|
37
|
+
3. Do not proceed to `dbt test` until run succeeds.
|
|
38
38
|
|
|
39
39
|
## test fails
|
|
40
40
|
|
|
@@ -15,8 +15,7 @@ project layout, finding gold models, resolving dbt model names to BigQuery table
|
|
|
15
15
|
creating bridge models from JSON arrays, and dbt validation commands.
|
|
16
16
|
|
|
17
17
|
If `create-dbt-transformations` is not installed: discover gold models directly via
|
|
18
|
-
`find dbt/models/gold -name "*.sql"
|
|
19
|
-
(`dbt parse`, `dbt run`, `dbt test`), and skip bridge model delegation.
|
|
18
|
+
`find dbt/models/gold -name "*.sql"` and skip bridge model delegation.
|
|
20
19
|
Warn the user: "The `create-dbt-transformations` skill is not installed — bridge model creation and dbt validation are limited."
|
|
21
20
|
|
|
22
21
|
If BigQuery exploration is needed (listing tables, inspecting schemas, previewing rows),
|
|
@@ -95,7 +94,7 @@ Follow these phases in order. Do not skip ahead.
|
|
|
95
94
|
|
|
96
95
|
1. Discover gold models via `find dbt/models/gold -name "*.sql"`.
|
|
97
96
|
2. If none exist, stop and tell the user to create gold models first via `create-dbt-transformations`.
|
|
98
|
-
3. Inspect 1-2 existing overlays in `semantic/` to detect conventions (
|
|
97
|
+
3. Inspect 1-2 existing overlays in `semantic/` to detect conventions (`extends:`, `public:`, `refresh_key` style). Apply detected conventions to new overlays. Always use flat single-cube YAML (never `cubes:` or `views:` root).
|
|
99
98
|
4. If the user named a specific model, find it. If not found, stop.
|
|
100
99
|
5. Otherwise list all discovered gold models and ask which should participate (Checkpoint 1).
|
|
101
100
|
6. Keep the full discovered list available for connector search in Phase 3.
|
|
@@ -238,13 +237,14 @@ Create Cube.dev YAML files in `semantic/`. Follow the existing style detected in
|
|
|
238
237
|
|
|
239
238
|
Key rules:
|
|
240
239
|
|
|
241
|
-
1.
|
|
242
|
-
2.
|
|
243
|
-
3.
|
|
244
|
-
4.
|
|
245
|
-
5.
|
|
246
|
-
6. `refresh_key.
|
|
247
|
-
7.
|
|
240
|
+
1. **One cube per file, flat YAML.** Each overlay file contains a single cube starting with `name:` at the root level. Never wrap with `cubes:` or `views:` at the root.
|
|
241
|
+
2. File name = cube `name` (no `gold_` prefix) + `.yml`.
|
|
242
|
+
3. `sql_table` uses fully qualified BigQuery reference with `gold_` prefix.
|
|
243
|
+
4. Every confirmed relationship gets joins in both directions.
|
|
244
|
+
5. Bridge/junction cubes use `public: false`.
|
|
245
|
+
6. Every overlay **must** include a SQL-based `refresh_key`. Use `SELECT MAX(<timestamp_col>)` with columns in this priority: `_airbyte_extracted_at` (present on all Airbyte sources), `updated_at`/`modified_at` (CDC streams), `created_at` (insert-only facts). Only use `every: <interval>` as absolute last resort when **no timestamp column exists in the table** — add a YAML comment explaining why (e.g. `# no timestamp column available`).
|
|
246
|
+
7. `refresh_key.sql` references the same table as `sql_table`.
|
|
247
|
+
8. Tag unvalidated joins with `# UNVALIDATED: <reason>`.
|
|
248
248
|
|
|
249
249
|
See [references/cube-examples.md](references/cube-examples.md) for canonical standard cube, bridge cube, join direction examples, and refresh key variants.
|
|
250
250
|
|
|
@@ -252,7 +252,7 @@ See [references/cube-examples.md](references/cube-examples.md) for canonical sta
|
|
|
252
252
|
|
|
253
253
|
## Phase 9: Validate Generated Files
|
|
254
254
|
|
|
255
|
-
1. If `create-dbt-transformations` was invoked (bridge model), it already validated dbt models. Otherwise run `
|
|
255
|
+
1. If `create-dbt-transformations` was invoked (bridge model), it already validated dbt models. Otherwise run `dbt parse`.
|
|
256
256
|
2. Verify physical tables exist in BigQuery: `bq show <dataset>.<table_name>`. If missing, document as pending.
|
|
257
257
|
3. Verify generated overlays match conventions: flat YAML, correct naming, correct `sql_table`, all dimensions present, `refresh_key` included, joins in both directions.
|
|
258
258
|
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
- [Refresh Key Variants](#refresh-key-variants)
|
|
10
10
|
- [Type Mapping](#type-mapping)
|
|
11
11
|
- [Measure Suggestions](#measure-suggestions)
|
|
12
|
+
- [Common Mistakes](#common-mistakes)
|
|
12
13
|
|
|
13
14
|
---
|
|
14
15
|
|
|
@@ -215,24 +216,68 @@ joins:
|
|
|
215
216
|
|
|
216
217
|
## Refresh Key Variants
|
|
217
218
|
|
|
218
|
-
|
|
219
|
+
SQL-based refresh keys are **required**. They ensure caches invalidate only when data actually changes, instead of on a fixed timer.
|
|
220
|
+
|
|
221
|
+
Priority — use the first available timestamp column:
|
|
219
222
|
|
|
220
223
|
```yaml
|
|
221
|
-
# 1. Airbyte timestamp (preferred)
|
|
224
|
+
# 1. Airbyte timestamp (preferred — present on all Airbyte sources)
|
|
222
225
|
refresh_key:
|
|
223
226
|
sql: "SELECT MAX(_airbyte_extracted_at) FROM `<dataset>.<gold_model>`"
|
|
224
227
|
|
|
225
|
-
# 2.
|
|
228
|
+
# 2. CDC / update timestamp
|
|
226
229
|
refresh_key:
|
|
227
230
|
sql: "SELECT MAX(updated_at) FROM `<dataset>.<gold_model>`"
|
|
228
231
|
|
|
229
|
-
# 3.
|
|
232
|
+
# 3. Insert-only fact table
|
|
230
233
|
refresh_key:
|
|
231
|
-
|
|
234
|
+
sql: "SELECT MAX(created_at) FROM `<dataset>.<gold_model>`"
|
|
235
|
+
|
|
236
|
+
# 4. Last resort — ONLY when the table has no timestamp column at all
|
|
237
|
+
# Add a comment explaining why:
|
|
238
|
+
refresh_key:
|
|
239
|
+
every: 1 hour # no timestamp column available in this table
|
|
232
240
|
```
|
|
233
241
|
|
|
234
242
|
`refresh_key.sql` must reference the same fully qualified table as the cube's `sql_table`.
|
|
235
243
|
|
|
244
|
+
### Common Mistakes
|
|
245
|
+
|
|
246
|
+
```yaml
|
|
247
|
+
# BAD — fixed cadence, ignores actual data changes.
|
|
248
|
+
# This forces cache rebuild every hour even when data hasn't changed.
|
|
249
|
+
refresh_key:
|
|
250
|
+
every: 1 hour
|
|
251
|
+
|
|
252
|
+
# GOOD — only invalidates when new rows arrive
|
|
253
|
+
refresh_key:
|
|
254
|
+
sql: "SELECT MAX(_airbyte_extracted_at) FROM `<dataset>.<gold_model>`"
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
```yaml
|
|
258
|
+
# BAD — omitting refresh_key entirely (cube uses default, which may be too aggressive)
|
|
259
|
+
name: my_cube
|
|
260
|
+
sql_table: ...
|
|
261
|
+
|
|
262
|
+
# GOOD — always include an explicit refresh_key
|
|
263
|
+
name: my_cube
|
|
264
|
+
sql_table: ...
|
|
265
|
+
refresh_key:
|
|
266
|
+
sql: "SELECT MAX(_airbyte_extracted_at) FROM `<dataset>.<gold_model>`"
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
```yaml
|
|
270
|
+
# BAD — refresh_key.sql references a different table than sql_table
|
|
271
|
+
sql_table: "`project.dataset.gold_orders`"
|
|
272
|
+
refresh_key:
|
|
273
|
+
sql: "SELECT MAX(_airbyte_extracted_at) FROM `project.dataset.gold_customers`"
|
|
274
|
+
|
|
275
|
+
# GOOD — same table in both
|
|
276
|
+
sql_table: "`project.dataset.gold_orders`"
|
|
277
|
+
refresh_key:
|
|
278
|
+
sql: "SELECT MAX(_airbyte_extracted_at) FROM `project.dataset.gold_orders`"
|
|
279
|
+
```
|
|
280
|
+
|
|
236
281
|
---
|
|
237
282
|
|
|
238
283
|
## Type Mapping
|
|
@@ -265,3 +310,36 @@ updated_at -> last_updated_at (max)
|
|
|
265
310
|
```
|
|
266
311
|
|
|
267
312
|
`count_distinct` on FK columns: define inside the cube that owns the FK, not the parent cube. Joins can produce row fan-out that distorts distinct counts.
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Common Mistakes
|
|
317
|
+
|
|
318
|
+
### Wrapping with `cubes:` or `views:` at the root
|
|
319
|
+
|
|
320
|
+
RevOS expects one cube per file with flat YAML — `name:` at the root level. The Cube.dev docs show a multi-cube `cubes:` list format, but RevOS does not use it.
|
|
321
|
+
|
|
322
|
+
```yaml
|
|
323
|
+
# BAD — multi-cube list format
|
|
324
|
+
cubes:
|
|
325
|
+
- name: hubspot_companies
|
|
326
|
+
sql_table: "`dataset.gold_hubspot_companies`"
|
|
327
|
+
dimensions:
|
|
328
|
+
id:
|
|
329
|
+
sql: "${CUBE}.id"
|
|
330
|
+
type: string
|
|
331
|
+
primary_key: true
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
```yaml
|
|
335
|
+
# GOOD — flat single-cube format
|
|
336
|
+
name: hubspot_companies
|
|
337
|
+
sql_table: "`dataset.gold_hubspot_companies`"
|
|
338
|
+
dimensions:
|
|
339
|
+
id:
|
|
340
|
+
sql: "${CUBE}.id"
|
|
341
|
+
type: string
|
|
342
|
+
primary_key: true
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Same applies to `views:` — never use it as a root key.
|
|
@@ -85,9 +85,13 @@ FROM \`$GOOGLE_CLOUD_PROJECT.$REVOS_BQ_DATASET.<table>\`
|
|
|
85
85
|
### "What's in my database?" / general overview
|
|
86
86
|
|
|
87
87
|
1. List tables in the org's dataset: `bq ls $REVOS_BQ_DATASET`
|
|
88
|
-
2.
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
2. If the dataset is empty (no tables), tell the user:
|
|
89
|
+
- They can add data sources by running `revos integrations create` to open the RevOS UI
|
|
90
|
+
- They can view existing integrations with `revos integrations list`
|
|
91
|
+
- Stop here — no further exploration is possible without data
|
|
92
|
+
3. Infer the data source and domain from table name prefixes (e.g. `salesforce_*`, `stripe_*`, `hubspot_*`)
|
|
93
|
+
4. Group tables by source/domain
|
|
94
|
+
5. Return: sources found, table count per source, table types (TABLE/VIEW), one-line description per group
|
|
91
95
|
|
|
92
96
|
### "What layer is this data?" / bronze–silver–gold assessment
|
|
93
97
|
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: load-sample-data
|
|
3
|
+
description: >
|
|
4
|
+
Populate a BigQuery dataset with sample data from public datasets using bq cp.
|
|
5
|
+
Use when asked to: load sample data, populate the lakehouse, add demo data, seed the dataset,
|
|
6
|
+
get started with sample tables, or when the user needs data to explore.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Load Sample Data
|
|
10
|
+
|
|
11
|
+
Copy sample tables from `bigquery-public-data` into the user's dataset using `bq cp`. All copied tables are prefixed with `sample_` so they can be easily identified and cleaned up later.
|
|
12
|
+
|
|
13
|
+
## Environment
|
|
14
|
+
|
|
15
|
+
Verify env vars before running any command. If either is empty, ask the user to set it.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
echo "Project: $GOOGLE_CLOUD_PROJECT"
|
|
19
|
+
echo "Dataset: $REVOS_BQ_DATASET"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- `$GOOGLE_CLOUD_PROJECT` — BQ project ID
|
|
23
|
+
- `$REVOS_BQ_DATASET` — target dataset
|
|
24
|
+
|
|
25
|
+
## Step 1: Check Existing Tables
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bq ls $REVOS_BQ_DATASET
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
If tables exist, list them. They will be relevant in Step 3 for collision handling.
|
|
32
|
+
|
|
33
|
+
## Step 2: Present Sample Dataset Catalog
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
Available sample datasets:
|
|
37
|
+
|
|
38
|
+
1. thelook_ecommerce (default) — B2C e-commerce data
|
|
39
|
+
Tables: sample_users, sample_orders, sample_order_items, sample_products, sample_events, sample_inventory_items, sample_distribution_centers
|
|
40
|
+
Rows: ~100K users, ~300K orders
|
|
41
|
+
Good for: customer analytics, purchase funnels, product performance
|
|
42
|
+
|
|
43
|
+
2. google_analytics_sample — Web analytics session data
|
|
44
|
+
Tables: sample_ga_sessions (single table, one day snapshot)
|
|
45
|
+
Rows: ~900K sessions
|
|
46
|
+
Good for: web traffic analysis, user behavior, channel attribution
|
|
47
|
+
|
|
48
|
+
3. austin_bikeshare — Bikeshare trip and station data
|
|
49
|
+
Tables: sample_bikeshare_trips, sample_bikeshare_stations
|
|
50
|
+
Rows: ~1.3M trips
|
|
51
|
+
Good for: geospatial analysis, demand forecasting, utilization metrics
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Step 3: Copy Tables
|
|
55
|
+
|
|
56
|
+
If any table names from the chosen sample dataset collide with existing tables (from Step 1), ask the user whether to **overwrite** or **skip** each collision before copying. Skip collisions the user chose not to overwrite.
|
|
57
|
+
|
|
58
|
+
### thelook_ecommerce
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
for table in users orders order_items products events inventory_items distribution_centers; do
|
|
62
|
+
echo "Copying sample_$table..."
|
|
63
|
+
bq cp -f bigquery-public-data:thelook_ecommerce.$table \
|
|
64
|
+
$GOOGLE_CLOUD_PROJECT:$REVOS_BQ_DATASET.sample_$table
|
|
65
|
+
done
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### google_analytics_sample
|
|
69
|
+
|
|
70
|
+
The `ga_sessions` table is date-sharded. Copy a representative day:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
echo "Copying sample_ga_sessions..."
|
|
74
|
+
bq cp -f bigquery-public-data:google_analytics_sample.ga_sessions_20170801 \
|
|
75
|
+
$GOOGLE_CLOUD_PROJECT:$REVOS_BQ_DATASET.sample_ga_sessions
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### austin_bikeshare
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
for table in bikeshare_trips bikeshare_stations; do
|
|
82
|
+
echo "Copying sample_$table..."
|
|
83
|
+
bq cp -f bigquery-public-data:austin_bikeshare.$table \
|
|
84
|
+
$GOOGLE_CLOUD_PROJECT:$REVOS_BQ_DATASET.sample_$table
|
|
85
|
+
done
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Step 4: Verify
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
for table in <copied_tables>; do
|
|
92
|
+
echo -n "$table: "
|
|
93
|
+
bq query --nouse_legacy_sql --format=csv \
|
|
94
|
+
"SELECT COUNT(*) FROM \`$GOOGLE_CLOUD_PROJECT.$REVOS_BQ_DATASET.$table\`" 2>/dev/null | tail -1
|
|
95
|
+
done
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Final Response
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
Sample data loaded into $REVOS_BQ_DATASET.
|
|
102
|
+
|
|
103
|
+
Source: bigquery-public-data:<dataset_name>
|
|
104
|
+
Tables copied:
|
|
105
|
+
- <table_1>: <row_count> rows
|
|
106
|
+
- <table_2>: <row_count> rows
|
|
107
|
+
|
|
108
|
+
Next steps:
|
|
109
|
+
- Run "explore lakehouse" to inspect the data
|
|
110
|
+
- Run "create dbt transformations" to build bronze/silver/gold models
|
|
111
|
+
- Run "create semantic model" to generate Cube overlays
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Rules
|
|
115
|
+
|
|
116
|
+
- Use `bq cp -f` (not `CREATE TABLE AS SELECT`) — faster, no query costs, preserves schema. The `-f` flag is required to avoid cross-region confirmation prompts that block non-interactive shells.
|
|
117
|
+
- Show progress for each table being copied.
|
|
118
|
+
- Report any failures clearly with the `bq` error message.
|
|
119
|
+
- Always prefix destination tables with `sample_` — this allows easy identification and cleanup of sample data.
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revos/cli",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "RevOS CLI for managing RevOS platform resources",
|
|
5
|
+
"license": "MIT",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"main": "dist/index.js",
|
|
7
8
|
"types": "dist/index.d.ts",
|
|
@@ -31,12 +32,16 @@
|
|
|
31
32
|
},
|
|
32
33
|
"overlays": {
|
|
33
34
|
"description": "Manage Cube overlays"
|
|
35
|
+
},
|
|
36
|
+
"integrations": {
|
|
37
|
+
"description": "Manage integrations (opens RevOS UI)"
|
|
34
38
|
}
|
|
35
39
|
}
|
|
36
40
|
},
|
|
37
41
|
"files": [
|
|
38
42
|
"dist",
|
|
39
|
-
"bin"
|
|
43
|
+
"bin",
|
|
44
|
+
"LICENSE"
|
|
40
45
|
],
|
|
41
46
|
"dependencies": {
|
|
42
47
|
"@inquirer/search": "^4.1.7",
|
|
@@ -57,7 +62,7 @@
|
|
|
57
62
|
"jest": "^29.7.0",
|
|
58
63
|
"tsdown": "^0.21.9",
|
|
59
64
|
"typescript": "^5.7.2",
|
|
60
|
-
"@
|
|
65
|
+
"@revos/config-eslint": "0.0.0"
|
|
61
66
|
},
|
|
62
67
|
"publishConfig": {
|
|
63
68
|
"registry": "https://registry.npmjs.org",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|