kpi_assembler 0.5.0 → 0.5.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.
- checksums.yaml +4 -4
- data/README.md +28 -54
- data/docs/integration.md +4 -2
- data/docs/rails-engine.md +25 -70
- data/docs/setup.md +236 -0
- data/lib/generators/kpi_assembler/install_generator.rb +2 -0
- data/lib/generators/kpi_assembler/templates/kpi_assembler.rb +1 -1
- data/lib/kpi_assembler/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f8327e4d084d6aef240991acae7bfed8ed06af1059fb28154e7ed911f4359976
|
|
4
|
+
data.tar.gz: f4d84ae33c76e3b8174358d60509a1e5091703b081f9d4ee73d5317f7940115b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 992360ae2eb9c585c7e5ea48841feb6ff177d92b827d734038b4abc152e08bb743dd52dd5b51b2f02f75d45e0bb1355b609f206d6f1fa054e8ad75fc661f3bb1
|
|
7
|
+
data.tar.gz: a57880ff32be45512aa1bf409991090549e07192c685647119298f4f5afc4ebb1880afbd168d5ce8f96ef5773daece8ebabab597eecc6e92de2c75057dd166d3
|
data/README.md
CHANGED
|
@@ -1,82 +1,56 @@
|
|
|
1
1
|
# KPIAssembler
|
|
2
2
|
|
|
3
|
-
KPIAssembler discovers application schemas, proposes
|
|
4
|
-
|
|
3
|
+
KPIAssembler discovers application schemas, proposes business metrics, and
|
|
4
|
+
certifies generated SQL before a number is trusted.
|
|
5
5
|
|
|
6
|
-
The LLM proposes
|
|
7
|
-
against the real schema, tenant boundary, SQL safety rules, query planner, and
|
|
8
|
-
sample execution before they can be marked certified.
|
|
6
|
+
The LLM proposes. Deterministic code certifies.
|
|
9
7
|
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
- Mountable Rails Engine with an interactive workspace and JSON API
|
|
13
|
-
- Standalone Rack application and command-line interface
|
|
14
|
-
- SQLite and PostgreSQL schema introspection
|
|
15
|
-
- Gemini and Ollama KPI proposal providers
|
|
16
|
-
- Schema-driven heuristic fallback when no model is available
|
|
17
|
-
- Deterministic SQL, join, division, tenant, and execution checks
|
|
18
|
-
- JSON and HTML KPI packs
|
|
19
|
-
|
|
20
|
-
## Install
|
|
21
|
-
|
|
22
|
-
Add the gem to your application:
|
|
8
|
+
## Install (Rails)
|
|
23
9
|
|
|
24
10
|
```ruby
|
|
25
|
-
|
|
11
|
+
# Gemfile
|
|
12
|
+
gem "kpi_assembler", "~> 0.5"
|
|
26
13
|
```
|
|
27
14
|
|
|
28
|
-
Then run:
|
|
29
|
-
|
|
30
15
|
```bash
|
|
31
16
|
bundle install
|
|
32
17
|
bin/rails generate kpi_assembler:install
|
|
33
18
|
```
|
|
34
19
|
|
|
35
|
-
Mount the engine:
|
|
36
|
-
|
|
37
20
|
```ruby
|
|
21
|
+
# config/routes.rb
|
|
38
22
|
mount KPIAssembler::Engine => "/kpi-assembler"
|
|
39
23
|
```
|
|
40
24
|
|
|
41
|
-
|
|
42
|
-
[standalone integration](docs/integration.md) for Rack, CLI, and API usage.
|
|
25
|
+
Then:
|
|
43
26
|
|
|
44
|
-
|
|
27
|
+
1. Edit `config/initializers/kpi_assembler.rb` (database pool, tenant, auth).
|
|
28
|
+
2. Set `GEMINI_API_KEY` and `KPI_LLM_PROVIDER=gemini` in the host `.env`,
|
|
29
|
+
or use Ollama / `KPI_USE_LLM=false`.
|
|
30
|
+
3. Restart the app and open `/kpi-assembler`.
|
|
45
31
|
|
|
46
|
-
|
|
32
|
+
Full walkthrough, env vars, and troubleshooting:
|
|
33
|
+
**[Setup guide](docs/setup.md)**.
|
|
47
34
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
GEMINI_API_KEY=your-key
|
|
51
|
-
KPI_GEMINI_MODEL=gemini-2.0-flash
|
|
52
|
-
```
|
|
35
|
+
Rails engine details: [docs/rails-engine.md](docs/rails-engine.md).
|
|
36
|
+
Standalone Rack/CLI/API: [docs/integration.md](docs/integration.md).
|
|
53
37
|
|
|
54
|
-
|
|
38
|
+
## What it does
|
|
55
39
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
Set `KPI_USE_LLM=false` to use schema-driven heuristics only.
|
|
63
|
-
|
|
64
|
-
## Development
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
bundle install
|
|
68
|
-
bundle exec rspec
|
|
69
|
-
bundle exec ruby bin/kpi_assembler --sample-db
|
|
70
|
-
bundle exec ruby bin/kpi_assembler_web
|
|
71
|
-
```
|
|
40
|
+
1. **Discover** — introspect tables, columns, and foreign keys
|
|
41
|
+
2. **Propose** — Gemini, Ollama, or schema heuristics draft KPI SQL
|
|
42
|
+
3. **Accept** — you choose which candidates to certify
|
|
43
|
+
4. **Certify** — read-only SELECT, join safety, tenant scope, planner, sample run
|
|
44
|
+
5. **Publish** — certified pack as JSON (and HTML from the CLI)
|
|
72
45
|
|
|
73
|
-
|
|
46
|
+
Rejected candidates never reach certification. **Draft** means a selected KPI
|
|
47
|
+
failed a certification check.
|
|
74
48
|
|
|
75
|
-
##
|
|
49
|
+
## Requirements
|
|
76
50
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
51
|
+
- Ruby >= 3.0
|
|
52
|
+
- Rails 7 for the engine
|
|
53
|
+
- Read-only database access (replica or reporting user)
|
|
80
54
|
|
|
81
55
|
## License
|
|
82
56
|
|
data/docs/integration.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Standalone integration
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
For the Rails engine, start with the [setup guide](setup.md).
|
|
4
|
+
|
|
5
|
+
KPIAssembler can also run as a Rack service and expose its workspace and JSON
|
|
6
|
+
API to applications written in any language.
|
|
5
7
|
|
|
6
8
|
## Start the service
|
|
7
9
|
|
data/docs/rails-engine.md
CHANGED
|
@@ -1,92 +1,47 @@
|
|
|
1
|
-
# Rails Engine
|
|
1
|
+
# Rails Engine notes
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Use this after the [setup guide](setup.md). KPIAssembler mounts inside a Rails 7
|
|
4
|
+
app, reuses the host session, and reads through Active Record.
|
|
5
5
|
|
|
6
|
-
##
|
|
7
|
-
|
|
8
|
-
```ruby
|
|
9
|
-
gem "kpi_assembler"
|
|
10
|
-
```
|
|
6
|
+
## Generator
|
|
11
7
|
|
|
12
8
|
```bash
|
|
13
9
|
bundle install
|
|
14
10
|
bin/rails generate kpi_assembler:install
|
|
15
11
|
```
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
```ruby
|
|
22
|
-
KPIAssembler.configure do |config|
|
|
23
|
-
config.connection_provider = lambda do |_controller|
|
|
24
|
-
ApplicationRecord.connected_to(role: :reading) do
|
|
25
|
-
ApplicationRecord.connection_pool
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
config.parent_controller = "ApplicationController"
|
|
30
|
-
config.tenant_column = "account_id"
|
|
31
|
-
config.tenant_id_resolver = lambda do |controller|
|
|
32
|
-
controller.send(:current_account).id
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
config.include_tables = []
|
|
36
|
-
config.max_tables = 30
|
|
37
|
-
config.schema_name = "public"
|
|
38
|
-
|
|
39
|
-
config.authorize_with = lambda do |controller|
|
|
40
|
-
controller.send(:authenticate_user!)
|
|
41
|
-
controller.send(:current_account).present?
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
config.llm_provider = ENV.fetch("KPI_LLM_PROVIDER", "gemini").to_sym
|
|
45
|
-
config.use_llm = ENV["KPI_USE_LLM"] != "false"
|
|
46
|
-
|
|
47
|
-
config.gemini_api_key = ENV["GEMINI_API_KEY"]
|
|
48
|
-
config.gemini_model = ENV.fetch("KPI_GEMINI_MODEL", "gemini-2.0-flash")
|
|
49
|
-
|
|
50
|
-
config.ollama_model = ENV.fetch("KPI_OLLAMA_MODEL", "llama3.2:3b")
|
|
51
|
-
config.ollama_url = ENV.fetch(
|
|
52
|
-
"KPI_OLLAMA_URL",
|
|
53
|
-
"http://localhost:11434/api/generate"
|
|
54
|
-
)
|
|
55
|
-
end
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Store secrets in the host application's environment rather than the initializer:
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
KPI_LLM_PROVIDER=gemini
|
|
62
|
-
GEMINI_API_KEY=your-key
|
|
63
|
-
KPI_GEMINI_MODEL=gemini-2.0-flash
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
Restart the Rails server after changing environment variables.
|
|
13
|
+
Creates `config/initializers/kpi_assembler.rb`. The template uses
|
|
14
|
+
`current_company` / `company_id` as placeholders — change them to match your
|
|
15
|
+
app (`current_account`, `tenant_id`, and so on).
|
|
67
16
|
|
|
68
|
-
##
|
|
69
|
-
|
|
70
|
-
Add the engine to `config/routes.rb`:
|
|
17
|
+
## Routes
|
|
71
18
|
|
|
72
19
|
```ruby
|
|
73
20
|
mount KPIAssembler::Engine => "/kpi-assembler"
|
|
74
21
|
```
|
|
75
22
|
|
|
76
|
-
The mounted endpoints are:
|
|
77
|
-
|
|
78
23
|
```text
|
|
79
24
|
GET/POST /kpi-assembler/api/v1/discover
|
|
80
25
|
POST /kpi-assembler/api/v1/certify
|
|
81
26
|
GET /kpi-assembler/api/v1/pack
|
|
82
27
|
```
|
|
83
28
|
|
|
84
|
-
|
|
29
|
+
Static UI files are served at `/kpi-assembler/assets/*` outside the host
|
|
30
|
+
controller stack so JavaScript is not blocked as a cross-origin response.
|
|
31
|
+
|
|
32
|
+
## Connection
|
|
33
|
+
|
|
34
|
+
`connection_provider` must return a pool or connection `KPIAssembler::Connection`
|
|
35
|
+
can wrap: `ActiveRecord::Base.connection_pool`, another pool, or a wrapped
|
|
36
|
+
adapter. Prefer `connected_to(role: :reading)` when the host has a replica.
|
|
37
|
+
|
|
38
|
+
## Tenancy
|
|
39
|
+
|
|
40
|
+
If `tenant_column` is set and that column exists on a fact table, every
|
|
41
|
+
certified query on that table must include `column = tenant_id`. Gemini often
|
|
42
|
+
omits this; certification then marks the KPI draft.
|
|
85
43
|
|
|
86
|
-
|
|
87
|
-
authorization callback with the host application's permission policy. Tenant
|
|
88
|
-
scoping must correspond to real columns in the inspected tables.
|
|
44
|
+
## Packs
|
|
89
45
|
|
|
90
|
-
The engine
|
|
91
|
-
|
|
92
|
-
invalidation policy.
|
|
46
|
+
The engine stores the latest pack in memory per tenant. Restarting the process
|
|
47
|
+
clears it. Persist packs in the host app before production use.
|
data/docs/setup.md
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# Setup guide
|
|
2
|
+
|
|
3
|
+
KPIAssembler inspects your application schema, proposes KPI definitions, and
|
|
4
|
+
certifies their SQL before anything is published. The model only proposes.
|
|
5
|
+
Deterministic Ruby certifies.
|
|
6
|
+
|
|
7
|
+
There are two install paths:
|
|
8
|
+
|
|
9
|
+
1. **Rails engine** — mount the workspace inside an existing Rails 7 app
|
|
10
|
+
2. **Standalone service** — run the Rack UI/API next to any application
|
|
11
|
+
|
|
12
|
+
Most teams should use the Rails engine.
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
- Ruby 3.0 or newer
|
|
17
|
+
- Rails 7.x for the engine (`railties >= 7.0, < 8`)
|
|
18
|
+
- A **read-only** database user, replica, or reporting pool
|
|
19
|
+
- Optional: a [Gemini API key](https://aistudio.google.com/apikey) or a local
|
|
20
|
+
[Ollama](https://ollama.com) daemon
|
|
21
|
+
|
|
22
|
+
Do not point certification at a production write primary.
|
|
23
|
+
|
|
24
|
+
## Rails engine
|
|
25
|
+
|
|
26
|
+
### 1. Add the gem
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
# Gemfile
|
|
30
|
+
gem "kpi_assembler", "~> 0.5"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bundle install
|
|
35
|
+
bin/rails generate kpi_assembler:install
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The generator writes `config/initializers/kpi_assembler.rb`.
|
|
39
|
+
|
|
40
|
+
### 2. Mount the workspace
|
|
41
|
+
|
|
42
|
+
In `config/routes.rb`, mount inside whatever scope already requires a signed-in
|
|
43
|
+
user:
|
|
44
|
+
|
|
45
|
+
```ruby
|
|
46
|
+
mount KPIAssembler::Engine => "/kpi-assembler"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Open `/kpi-assembler` after signing in.
|
|
50
|
+
|
|
51
|
+
JSON endpoints:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
GET/POST /kpi-assembler/api/v1/discover
|
|
55
|
+
POST /kpi-assembler/api/v1/certify
|
|
56
|
+
GET /kpi-assembler/api/v1/pack
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 3. Edit the initializer
|
|
60
|
+
|
|
61
|
+
Replace the sample hooks with your app's connection, tenant, and auth.
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
KPIAssembler.configure do |config|
|
|
65
|
+
# Prefer a read/report pool, not the write primary.
|
|
66
|
+
config.connection_provider = lambda do |_controller|
|
|
67
|
+
ApplicationRecord.connected_to(role: :reading) do
|
|
68
|
+
ApplicationRecord.connection_pool
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
config.parent_controller = "ApplicationController"
|
|
73
|
+
|
|
74
|
+
# Column that exists on fact tables. Omit tenant_column if you have none.
|
|
75
|
+
config.tenant_column = "account_id"
|
|
76
|
+
config.tenant_id_resolver = lambda do |controller|
|
|
77
|
+
controller.send(:current_account).id
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Empty allowlist = inspect the live schema (up to max_tables).
|
|
81
|
+
# Names must match the database (people, not Person).
|
|
82
|
+
config.include_tables = []
|
|
83
|
+
config.max_tables = 30
|
|
84
|
+
config.schema_name = "public"
|
|
85
|
+
|
|
86
|
+
config.authorize_with = lambda do |controller|
|
|
87
|
+
controller.send(:authenticate_user!)
|
|
88
|
+
controller.send(:current_account).present?
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
config.llm_provider = ENV.fetch("KPI_LLM_PROVIDER", "gemini").to_sym
|
|
92
|
+
config.use_llm = ENV["KPI_USE_LLM"] != "false"
|
|
93
|
+
config.gemini_api_key = ENV["GEMINI_API_KEY"]
|
|
94
|
+
config.gemini_model = ENV.fetch("KPI_GEMINI_MODEL", "gemini-2.0-flash")
|
|
95
|
+
config.ollama_model = ENV.fetch("KPI_OLLAMA_MODEL", "llama3.2:3b")
|
|
96
|
+
config.ollama_url = ENV.fetch("KPI_OLLAMA_URL", "http://localhost:11434/api/generate")
|
|
97
|
+
end
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
If you have no `reading` role, return `ActiveRecord::Base.connection_pool`
|
|
101
|
+
(still with a read-only user).
|
|
102
|
+
|
|
103
|
+
### 4. Set environment variables
|
|
104
|
+
|
|
105
|
+
Put secrets in the host app `.env` (or your secret manager). Do not commit keys.
|
|
106
|
+
|
|
107
|
+
**Gemini (cloud):**
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
KPI_LLM_PROVIDER=gemini
|
|
111
|
+
GEMINI_API_KEY=your-key
|
|
112
|
+
KPI_GEMINI_MODEL=gemini-2.0-flash
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
You do not set a Gemini URL. The default endpoint is built from the model name.
|
|
116
|
+
|
|
117
|
+
**Ollama (local):**
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
KPI_LLM_PROVIDER=ollama
|
|
121
|
+
KPI_OLLAMA_MODEL=llama3.2:3b
|
|
122
|
+
KPI_OLLAMA_URL=http://localhost:11434/api/generate
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Start the daemon first: `ollama serve`, then `ollama pull llama3.2:3b`.
|
|
126
|
+
|
|
127
|
+
**Heuristics only:**
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
KPI_USE_LLM=false
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Restart `bin/rails server` after changing env vars or the initializer.
|
|
134
|
+
|
|
135
|
+
### 5. First run
|
|
136
|
+
|
|
137
|
+
1. Sign in and open `/kpi-assembler`.
|
|
138
|
+
2. Click **Discover metrics**. Schema cards and candidate KPIs should appear.
|
|
139
|
+
3. Select the definitions you want. Rejected items never reach certification.
|
|
140
|
+
4. Click **Certify**. Certified KPIs become the pack. Failures land in **draft**
|
|
141
|
+
with reasons (unsafe SQL, missing tenant scope, planner error, NULL sample
|
|
142
|
+
replay). Draft is not the same as rejecting a KPI in the UI.
|
|
143
|
+
|
|
144
|
+
The workspace shows whether the proposer was `llm` or `heuristics`, the model
|
|
145
|
+
name, and any tables the model ranked.
|
|
146
|
+
|
|
147
|
+
## Configuration reference
|
|
148
|
+
|
|
149
|
+
| Setting | Purpose |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `connection_provider` | Returns an AR pool or connection used for inspect + certify |
|
|
152
|
+
| `tenant_column` / `tenant_id_resolver` | Injects tenant filters into generated SQL |
|
|
153
|
+
| `include_tables` | Optional allowlist. Empty means inspect the live schema |
|
|
154
|
+
| `max_tables` | Cap after ranking; omitted tables are reported in the UI |
|
|
155
|
+
| `schema_name` | PostgreSQL schema (default `public`) |
|
|
156
|
+
| `parent_controller` | Host controller the engine inherits (auth callbacks) |
|
|
157
|
+
| `authorize_with` | Extra gate; must not return `false` |
|
|
158
|
+
| `llm_provider` | `:gemini` or `:ollama` |
|
|
159
|
+
| `use_llm` | `false` skips the model and uses schema heuristics |
|
|
160
|
+
| `gemini_api_key` / `gemini_model` | Gemini credentials |
|
|
161
|
+
| `ollama_model` / `ollama_url` | Local Ollama |
|
|
162
|
+
|
|
163
|
+
Environment variables the gem reads: `KPI_LLM_PROVIDER`, `KPI_USE_LLM`,
|
|
164
|
+
`GEMINI_API_KEY`, `KPI_GEMINI_MODEL`, `KPI_GEMINI_URL`, `KPI_OLLAMA_MODEL`,
|
|
165
|
+
`KPI_OLLAMA_URL`, `KPI_USE_OLLAMA` (Ollama-only off switch).
|
|
166
|
+
|
|
167
|
+
## Standalone service
|
|
168
|
+
|
|
169
|
+
Use this when the host app is not Rails, or you want a separate process.
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
gem install kpi_assembler
|
|
173
|
+
# or clone the repo and: bundle install
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
From the gem source checkout:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
cp .env.example .env
|
|
180
|
+
# set KPI_DATABASE_URL or KPI_DATABASE_PATH, plus LLM vars
|
|
181
|
+
bundle exec ruby bin/kpi_assembler_web
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Opens `http://127.0.0.1:9292`.
|
|
185
|
+
|
|
186
|
+
Useful env vars:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
HOST=0.0.0.0
|
|
190
|
+
PORT=9292
|
|
191
|
+
KPI_DATABASE_URL=postgres://USER:PASSWORD@HOST:5432/application
|
|
192
|
+
KPI_DATABASE_PATH=/absolute/path/to/application.sqlite3
|
|
193
|
+
KPI_INCLUDE_TABLES=orders,customers,accounts
|
|
194
|
+
KPI_TENANT_COLUMN=account_id
|
|
195
|
+
KPI_TENANT_ID=123
|
|
196
|
+
KPI_ALLOWED_ORIGIN=https://your-app.example
|
|
197
|
+
KPI_LLM_PROVIDER=gemini
|
|
198
|
+
GEMINI_API_KEY=your-key
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Embed:
|
|
202
|
+
|
|
203
|
+
```html
|
|
204
|
+
<script src="http://localhost:9292/kpi-assembler.js"></script>
|
|
205
|
+
<kpi-assembler service-url="http://localhost:9292" height="820px"></kpi-assembler>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
CLI against the sample database:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
bundle exec ruby bin/kpi_assembler --sample-db
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
See [standalone integration](integration.md) for the JSON API.
|
|
215
|
+
|
|
216
|
+
## Troubleshooting
|
|
217
|
+
|
|
218
|
+
| Symptom | What to check |
|
|
219
|
+
| --- | --- |
|
|
220
|
+
| Discover does nothing / non-JSON error | Host redirected to login. Send the request while signed in. Confirm `/kpi-assembler/assets/app.js` returns 200. |
|
|
221
|
+
| `heuristics` proposer, Gemini fallback | `GEMINI_API_KEY` missing or HTTP error. The UI shows `proposer_fallback`. |
|
|
222
|
+
| `heuristics` proposer, Ollama fallback | `ollama serve` not running, or model not pulled. Fallback text names installed models. |
|
|
223
|
+
| UI does not show tables you added | `include_tables` names must match the DB. Check `missing_tables` / `omitted_tables` (`max_tables`). |
|
|
224
|
+
| Many KPIs become **draft** after certify | Open `reasons`. Common: missing `tenant_column = id`, invented tables, `NULLIF` producing NULL on empty windows. |
|
|
225
|
+
| `json` / `quirks_mode` on Rails 7 | Pin `gem "json", "< 3"` in the **host** Gemfile. |
|
|
226
|
+
| Slow or truncated LLM output | Lower `max_tables`, or use `gemini-2.0-flash` / a small Ollama model. |
|
|
227
|
+
|
|
228
|
+
## Security
|
|
229
|
+
|
|
230
|
+
- Authorize the mount the same way as the rest of the app. The extra
|
|
231
|
+
`authorize_with` gate is not a substitute for a real permission check.
|
|
232
|
+
- Certification **executes** candidate `SELECT`s. Use a least-privilege
|
|
233
|
+
read-only role.
|
|
234
|
+
- Tenant SQL is only injected when `tenant_column` exists on the fact table.
|
|
235
|
+
- The latest pack is kept in process memory per tenant. Persist packs yourself
|
|
236
|
+
before relying on this in production.
|
|
@@ -19,6 +19,8 @@ module KPIAssembler
|
|
|
19
19
|
def print_mount_instruction
|
|
20
20
|
say "\nMount KPIAssembler in config/routes.rb:", :green
|
|
21
21
|
say ' mount KPIAssembler::Engine => "/kpi-assembler"'
|
|
22
|
+
say "\nThen set GEMINI_API_KEY (or KPI_LLM_PROVIDER=ollama) and restart."
|
|
23
|
+
say "Setup guide: https://github.com/Akshatsrivastava700/kpi_assembler/blob/main/docs/setup.md"
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
end
|
|
@@ -42,6 +42,6 @@ KPIAssembler.configure do |config|
|
|
|
42
42
|
config.gemini_model = ENV.fetch("KPI_GEMINI_MODEL", "gemini-2.0-flash")
|
|
43
43
|
|
|
44
44
|
# Ollama configuration
|
|
45
|
-
config.ollama_model = ENV.fetch("KPI_OLLAMA_MODEL", "llama3")
|
|
45
|
+
config.ollama_model = ENV.fetch("KPI_OLLAMA_MODEL", "llama3.2:3b")
|
|
46
46
|
config.ollama_url = ENV.fetch("KPI_OLLAMA_URL", "http://localhost:11434/api/generate")
|
|
47
47
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kpi_assembler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- KPIAssembler contributors
|
|
@@ -47,6 +47,7 @@ files:
|
|
|
47
47
|
- config/routes.rb
|
|
48
48
|
- docs/integration.md
|
|
49
49
|
- docs/rails-engine.md
|
|
50
|
+
- docs/setup.md
|
|
50
51
|
- lib/generators/kpi_assembler/install_generator.rb
|
|
51
52
|
- lib/generators/kpi_assembler/templates/kpi_assembler.rb
|
|
52
53
|
- lib/kpi_assembler.rb
|
|
@@ -79,6 +80,7 @@ metadata:
|
|
|
79
80
|
homepage_uri: https://github.com/Akshatsrivastava700/kpi_assembler
|
|
80
81
|
source_code_uri: https://github.com/Akshatsrivastava700/kpi_assembler
|
|
81
82
|
changelog_uri: https://github.com/Akshatsrivastava700/kpi_assembler/releases
|
|
83
|
+
documentation_uri: https://github.com/Akshatsrivastava700/kpi_assembler/blob/main/docs/setup.md
|
|
82
84
|
post_install_message:
|
|
83
85
|
rdoc_options: []
|
|
84
86
|
require_paths:
|