-
Notifications
You must be signed in to change notification settings - Fork 0
fix: Remove hardcoded Gemini API key #50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2d55b7e
1394d78
47ae092
a1a0406
ced4994
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| name: OTOP Static Checks | ||
| on: | ||
| pull_request: | ||
| push: | ||
|
|
||
| jobs: | ||
| otop: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: UI ID audit (non-blocking report) | ||
| run: | | ||
| if [ -f scripts/otop-uiid-audit.sh ]; then | ||
| bash scripts/otop-uiid-audit.sh || true | ||
| cat otop.audit.uiids.md || true | ||
| else | ||
| echo "No UI audit script." | ||
| fi | ||
|
|
||
| - name: Hardcoded URL audit (block on critical findings) | ||
| run: | | ||
| if [ -f scripts/otop-env-audit.sh ]; then | ||
| bash scripts/otop-env-audit.sh || true | ||
| # fail if we find hardcoded localhost or obvious prod domains in src/ (tune as needed) | ||
| if rg -n "http://localhost:|https://api\." . -g'!**/node_modules/**' -g'!**/dist/**' -g'!**/build/**' -g'!**/.next/**' -g'!**/.venv/**' ; then | ||
| echo "Hardcoded URL found. Move to ENV/proxy." | ||
| exit 1 | ||
| fi | ||
| else | ||
| echo "No env audit script." | ||
| fi | ||
|
|
||
| - name: OpenAPI lint (block if spec exists and fails) | ||
| run: | | ||
| if [ -f scripts/otop-openapi-lint.sh ]; then | ||
| bash scripts/otop-openapi-lint.sh | ||
| else | ||
| echo "No OpenAPI lint script." | ||
| fi | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| # OTOP Standard (Repo-weit) | ||
|
|
||
| ## Ziel | ||
| 1) **Backend-Funktionen** sind eindeutig & stabil referenzierbar (OpenAPI `operationId`). | ||
| 2) **UI-Elemente** sind eindeutig & stabil referenzierbar (`data-otop-id` / `data-testid`). | ||
| 3) **Verbindung** Frontend↔Backend ist robust (keine hardcoded URLs). | ||
|
|
||
| --- | ||
|
|
||
| ## 1) Backend Standard (OpenAPI = Function Registry) | ||
|
|
||
| ### Pflicht | ||
| - Jede REST-Operation MUSS besitzen: | ||
| - `operationId` (eindeutig innerhalb der Spec) | ||
| - `tags` (mind. 1 Tag; dient als Gruppierung im Tool) | ||
|
|
||
| ### operationId Konvention (deterministisch) | ||
| **Format:** `{tagSlug}_{method}_{pathSlug}` | ||
|
|
||
| Beispiele: | ||
| - Tag: `Tasks`, Methode: `POST`, Pfad: `/tasks` | ||
| → `tasks_post_tasks` | ||
| - Tag: `Candidates`, Methode: `GET`, Pfad: `/candidates/{id}` | ||
| → `candidates_get_candidates_id` | ||
|
|
||
| **Regeln:** | ||
| - `tagSlug` = lower + `_` statt Leerzeichen | ||
| - `pathSlug` = path ohne führenden `/`, `/`→`_`, `{id}`→`id` | ||
| - Keine Sonderzeichen, nur `[a-z0-9_]` | ||
|
|
||
| ### Tags Konvention | ||
| - Tags sollten “Menü-Struktur” im OTOP Tool abbilden: | ||
| - `Auth`, `Agents`, `Tasks`, `CRM`, `Telephony`, `Admin`, `Utils` | ||
| - Optional: “Substruktur” im Tag-Name: `CRM/Candidates`, `CRM/Jobs` | ||
|
|
||
| ### Health/Ready (empfohlen) | ||
| - `/health` (liveness) | ||
| - `/ready` (readiness; z.B. DB/Queue ready) | ||
|
|
||
| --- | ||
|
|
||
| ## 2) Frontend Standard (UI IDs = Link Targets) | ||
|
|
||
| ### Web (React/Vite/Next) | ||
| Jede interaktive Komponente MUSS haben: | ||
| - `data-testid` | ||
| - `data-otop-id` | ||
|
|
||
| **ID Schema:** `{domain}.{entity}.{screen}.{component}.{action}` | ||
|
|
||
| Beispiele: | ||
| - `crm.candidate.list.search.input` | ||
| - `crm.candidate.list.create.button` | ||
| - `crm.candidate.form.save.button` | ||
| - `agents.task.detail.disable.toggle` | ||
|
|
||
| **Beispiel:** | ||
| ```tsx | ||
| <button | ||
| data-testid="crm.candidate.list.create.button" | ||
| data-otop-id="crm.candidate.list.create.button" | ||
| > | ||
| Create | ||
| </button> | ||
| ``` | ||
|
|
||
| ### React Native (Expo) | ||
| React Native nutzt kein `data-*`, darum: | ||
| - `testID` (Tests & Tool-Anker) | ||
| - `accessibilityLabel` (OTOP-Label, stabil) | ||
|
|
||
| ```tsx | ||
| <TouchableOpacity | ||
| testID="crm.candidate.list.create.button" | ||
| accessibilityLabel="otop:crm.candidate.list.create.button" | ||
| > | ||
| <Text>Create</Text> | ||
| </TouchableOpacity> | ||
| ``` | ||
|
|
||
| ### Flutter | ||
| ```dart | ||
| ElevatedButton( | ||
| key: const Key('crm.candidate.list.create.button'), | ||
| onPressed: () {}, | ||
| child: const Text('Create'), | ||
| ) | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 3) Verbindung Frontend ↔ Backend (keine hardcoded URLs) | ||
| Erlaubt: | ||
| - Proxy `/api/*` (best) | ||
| - ENV `*_API_BASE_URL` (ok) | ||
|
|
||
| Verboten: | ||
| - Hardcoded Domains/Ports im Code (`http://localhost:...`, `https://api...`) | ||
|
|
||
| --- | ||
|
|
||
| ## 4) Definition of Done (für “Fertigstellung”) | ||
| Ein UI gilt als „fertig“, wenn: | ||
| - alle benötigten Backend-Funktionen entweder | ||
| - **verlinkt** sind (UI-ID → operationId), oder | ||
| - bewusst als **deaktiviert** markiert sind | ||
| - Delete/Disable/Unlink erzeugt Warnung über Auswirkungen (Dependencies) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| Du bist Produkt+Frontend-Architekt. | ||
|
|
||
| INPUT: | ||
| - OpenAPI Spec (JSON/YAML) oder OpenAPI URL | ||
| - Ziel: UI Blueprint aus OpenAPI ableiten (Screens/Buttons/Felder/States) | ||
| - Regeln: | ||
| - Gruppiere nach Tags. | ||
| - Für jede Entity: List + Detail + Create + Edit + Delete Confirm. | ||
| - Aus Request Schemas: required/optional Felder + enums ableiten. | ||
| - Jede Action referenziert operationId + method + path. | ||
| - Jeder Screen hat Loading/Error/Empty/Success. | ||
|
|
||
| OUTPUT FORMAT: | ||
| - SECTION: <Tag> | ||
| - ENTITY: <Entity> | ||
| - SCREEN: <Name> | ||
| - PURPOSE: | ||
| - UI ELEMENTS: | ||
| - BUTTONS (mit UI-ID Schema): | ||
| - API LINKS (operationId → method path): | ||
| - STATES: |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| Du bist v0 Prompt-Writer (React + Tailwind + shadcn/ui). | ||
|
|
||
| INPUT: | ||
| - UI BLUEPRINT (aus 01) | ||
| - Regeln: | ||
| - shadcn/ui verwenden (Button, Dialog, Table, Input, Select, Tabs, Toast) | ||
| - Jeder interaktive Control bekommt data-otop-id + data-testid | ||
| - Delete immer mit Confirm Dialog | ||
| - List: Search + Filter + Pagination + Empty/Loading/Error | ||
| - Forms: required validation + disabled submit + success toast | ||
| - API Calls als Platzhalter: api.<operationId>(params) | ||
|
|
||
| OUTPUT: | ||
| - Gib nur den fertigen v0 Prompt aus. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| Du bist Frontend-Integrator. | ||
|
|
||
| INPUT: | ||
| - UI BLUEPRINT | ||
| - Generated client: Orval (React Query) oder openapi-fetch oder OpenAPI Generator SDK | ||
| - Regeln: | ||
| - Verwende ausschließlich generated client/hooks. | ||
| - Keine hardcoded URLs. | ||
| - Jede Mutation invalidiert betroffene Lists (z.B. create invalidiert list). | ||
|
|
||
| OUTPUT: | ||
| - SCREEN: <name> | ||
| - READS: | ||
| - MUTATIONS: | ||
| - PARAM MAPPING: | ||
| - UI STATES: | ||
| - CACHE/INVALIDATION: |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| Du bist QA/Reviewer. | ||
|
|
||
| INPUT: | ||
| - UI BLUEPRINT | ||
| - Regeln: | ||
| - Buttons: Create/Edit/Delete/Save/Cancel vorhanden | ||
| - Delete Confirm vorhanden | ||
| - required validation vorhanden | ||
| - Loading/Error/Empty/Success vorhanden | ||
| - data-otop-id + data-testid überall | ||
| - Buttons referenzieren die richtige operationId | ||
|
|
||
| OUTPUT: | ||
| - SCREEN: ... | ||
| - [ ] ... |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| # Retrofit Guide (rückwirkend umstellen) | ||
|
|
||
| ## Warum rückwirkend in Schritten? | ||
| Wenn du „alles auf einmal“ in 22 Repos umstellst, entsteht Chaos (Merge-Konflikte, UI-Brüche). Darum: | ||
|
|
||
| 1) **Standards + Checks überall einführen** (OTOP Pack) | ||
| 2) **Baselines/Reports erzeugen** (Audit) | ||
| 3) **Gezielt nachziehen** (repoweise, screenweise) | ||
|
|
||
| --- | ||
|
|
||
| ## Schritt 1: Pack in alle Repos übernehmen | ||
| - `bash otop-pack-v1/scripts/otop-install.sh <root-mit-repos>` | ||
|
|
||
| Das kopiert: | ||
| - `docs/otop-standard.md` | ||
| - `docs/prompts/*` | ||
| - `rules/spectral-otop.yml` | ||
| - `scripts/*` | ||
| - `.github/workflows/otop-*.yml` (statische Checks) | ||
| - Ergänzt optional `AGENTS.md` | ||
|
|
||
| --- | ||
|
|
||
| ## Schritt 2: Baseline pro Repo erzeugen | ||
| In jedem Repo: | ||
| ```bash | ||
| bash scripts/otop-scan.sh | ||
| bash scripts/otop-uiid-audit.sh | ||
| bash scripts/otop-openapi-lint.sh | ||
| bash scripts/otop-env-audit.sh | ||
| ``` | ||
|
|
||
| Ergebnis: | ||
| - `otop.config.json` (Scan) | ||
| - `otop.audit.uiids.md` (UI-ID Coverage) | ||
| - `otop.audit.env.md` (Hardcoded URL Findings) | ||
| - Lint-Output für OpenAPI | ||
|
|
||
| --- | ||
|
|
||
| ## Schritt 3: Priorisierung (empfohlen) | ||
| Basierend auf deinem aktuellen Report: | ||
| - **partner**: Hardcoded URLs → ENV (kritisch, sonst nie sauber deploybar) | ||
| - **CRM-activi**: OpenAPI ohne operationId → nicht verlinkbar | ||
| - **code-cloud-agents / Optimizecodecloudagents**: OpenAPI+Health ok, aber UI-IDs fehlen komplett | ||
|
|
||
| --- | ||
|
|
||
| ## Schritt 4: UI IDs rückwirkend einführen (Web) | ||
| ### 4.1 Schnellster Hebel: “Design System Wrapper” | ||
| Lege zentral Komponenten an, die IDs erzwingen: | ||
| - `OButton`, `OInput`, `OSelect`, `OLink` | ||
| - Props: `otopId` (string), setzt automatisch beide Attribute | ||
|
|
||
| Dann ersetzt du schrittweise: | ||
| - `<Button ...>` → `<OButton otopId="..." ...>` | ||
|
|
||
| ### 4.2 Heuristik für IDs (damit KI konsistent bleibt) | ||
| - Domain: `crm|agents|auth|telephony|admin|utils` | ||
| - entity: `candidate|job|task|agent|user|...` | ||
| - screen: `list|detail|form|settings|...` | ||
| - component: `table|search|modal|toolbar|...` | ||
| - action: `create|save|delete|edit|open|close|...` | ||
|
|
||
| ### 4.3 Minimalziel pro Screen | ||
| - Primary Buttons (Create/Save/Delete/Cancel) | ||
| - Inputs/Selects im Form | ||
| - Navigation Tabs/Links | ||
|
|
||
| --- | ||
|
|
||
| ## Schritt 5: UI IDs rückwirkend einführen (React Native) | ||
| - `testID` + `accessibilityLabel="otop:<id>"` | ||
| - Für “Custom Buttons” zentral Wrapper `OButtonRN` bauen, der beide setzt. | ||
|
|
||
| --- | ||
|
|
||
| ## Schritt 6: OpenAPI operationId rückwirkend ergänzen | ||
| Wenn OpenAPI im Repo liegt: | ||
| - Führe `python scripts/otop-add-operationid.py api/openapi.yaml` aus | ||
| - Danach `bash scripts/otop-openapi-lint.sh` | ||
|
|
||
| --- | ||
|
|
||
| ## Schritt 7: “Stop the bleeding” | ||
| Sobald ein Repo angefangen hat: | ||
| - CI/PR-Checks aktivieren, die neue UI ohne IDs blocken | ||
| - OpenAPI ohne operationId blocken | ||
|
|
||
| So wächst die Qualität automatisch. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,8 +4,8 @@ import 'package:google_generative_ai/google_generative_ai.dart'; | |
| import 'user_profile_service.dart'; | ||
|
|
||
| class GeminiService { | ||
| // Free tier API key - 15 requests/minute, 1500/day | ||
| static const String _apiKey = 'AIzaSyD5jBRl-Ti0r_uSyx5JW24H3CySQ8RWrS8'; | ||
| // API key from environment variable (dart-define) | ||
| static const String _apiKey = String.fromEnvironment('GEMINI_API_KEY', defaultValue: ''); | ||
|
Comment on lines
+7
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Because Useful? React with 👍 / 👎. |
||
|
|
||
| GenerativeModel? _model; | ||
| ChatSession? _chat; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
ripgrep rg pre-installed GitHub Actions ubuntu-latest runner 2024 2025💡 Result:
Short answer: GitHub moved ubuntu-latest to Ubuntu 24.04 (rollout Dec 5, 2024–Jan 17, 2025). Whether rg (ripgrep) is present can differ between image versions — GitHub's image manifests don't list every utility — so you should verify at runtime (rg --version) and install it in your workflow if you need it guaranteed (apt install -y ripgrep). [1][2][3]
How to check in a job:
How to install if missing:
Sources:
References:
[1] actions/runner-images repository — Available Images. (github.com)
[2] GitHub-hosted runners reference (Docs). (docs.github.com)
[3] Issue announcing ubuntu-latest -> Ubuntu 24.04 rollout (Dec 5, 2024 — Jan 17, 2025). (github.com)
Citations:
Add explicit ripgrep installation to ensure workflow reliability.
Ripgrep (
rg) is not guaranteed to be pre-installed on GitHub Actionsubuntu-latestrunners. The hardcoded URL audit step (line 26) assumes its availability, which will cause the workflow to fail unexpectedly if it's missing.Add an installation step before the audit:
Alternatively, check for availability and install conditionally:
🤖 Prompt for AI Agents