Initialen Implementierungsplan hinzugefügt

This commit is contained in:
2026-04-08 08:37:58 +02:00
commit 39390e94e5
3 changed files with 684 additions and 0 deletions

266
CLAUDE.md Normal file
View File

@@ -0,0 +1,266 @@
# CLAUDE.md — Oracle Database
## Projektbeschreibung
Projekt für verschiedene Oracle-Datenbank Entwicklungen.
Enthält Tabellendefinitionen, PL/SQL-Packages, ORDS-Endpunkte, Views, Trigger etc.
## SQL / PL/SQL Guidelines
### Formatierung
**Keywords immer klein:**
```sql
select, from, where, insert into, create table, begin, end, exception, ...
```
**Tab-Ausrichtung in mehrzeiligen Statements:**
Schlüsselwort + Tab, dann Inhalt. Erste Spalte und alle nachfolgenden Kommas stehen auf
demselben Tab-Stop (eine Fluchtlinie). Komma direkt vor dem Spaltennamen ohne Leerzeichen.
```sql
select order_id
,principal_order_number
,total_amount
from fgt_order
where status = 'COMPLETE'
```
```sql
insert into fgt_order (
order_id
,principal_order_number
,total_amount
) values (
fgt_order_seq.nextval
,p_order_number
,p_total_amount
);
```
**Block-Keywords in eigener Zeile (lineup bracing):**
`loop`, `then`, `exception` und ihre schließenden `end`-Varianten stehen auf gleicher
Einrückungsebene wie der Block-Öffner:
```sql
for rec in cur_open_orders
loop
l_count := l_count + 1;
end loop;
if l_count > 0
then
do_something();
elsif l_count < 0
then
handle_negative();
end if;
begin
l_result := do_something();
exception
when e_not_found
then
l_result := null;
when others
then
raise;
end;
```
**`end`-Anweisungen immer mit Label:**
```sql
end my_procedure;
end my_package;
```
**Indentation:** 4 Spaces innerhalb von Blöcken.
---
### Benennungskonventionen
| Objekt | Konvention | Beispiel |
|---|---|---|
| Tabellen | Modulabhängiger Präfix, z.B.`adr_`, **Singular**, Dateiendung `.tab` | `sy_parameter`, `adr_adresse_zuweisung`, |
| Views | `v_` Präfix | `v_adr_adresse_zuweisung` |
| Packages | `pck_` Präfix, Separate header und body Dateien mit den Endungen `.pkh` und `.pkb` | `pck_system` |
| Prozeduren | `p_`-Präfix | `p_insert_order`, `p_delete_folder` |
| Funktionen | `f_`-Präfix | `f_get_order`, `f_build_url` |
| Lokale Variablen | `l_`-Präfix | `l_order_id`, `l_count` |
| Parameter (Input) | `i_`-Präfix | `i_json`, `i_order_id` |
| Package-globale Variablen | `g_`-Präfix | `g_default_currency` |
| Konstanten | `c_`-Präfix | `c_max_retries` |
| Cursor | `cur_`-Präfix | `cur_open_orders` |
| Exceptions | `e_`-Präfix | `e_not_found`, `e_duplicate` |
| Views | `_v`-Suffix | `fgt_order_v` |
| Trigger | `trg_`-Präfix | `trg_fgt_order_created_at` |
| Sequences | `<zweck>_seq` | `fgt_order_id_seq` |
| Primary Key (Spalte) | `<tabellenname>_id` | `order_id`, `shipment_id` |
| Foreign Key (Constraint) | `<beschreibung>_fk` | `fgt_order_bill_addr_fk` |
---
### PL/SQL-Struktur
- `as` für Package-Spec/Body-Header, `is` für Prozedur-/Funktionskörper innerhalb eines Packages
- Implizite Cursor-FOR-Loops bevorzugen gegenüber expliziten Cursors
- `is null` / `is not null` verwenden — niemals `= null` / `!= null`
- Explizite Formatmasken in `to_date`, `to_char`, `to_timestamp`
- `commit` nur im äußersten Aufrufer — nie in Sub-Prozeduren
```sql
create or replace package body pck_orders as
procedure insert_order (i_json in clob, i_run_id in varchar2)
is
l_order_id number;
l_status varchar2(20);
begin
-- Implementierung
l_order_id := bet_order_id_seq.nextval;
end insert_order;
end fgt_orders;
```
---
### Exception Handling
- **Niemals** `when others then null` — Exceptions nie stillschweigend schlucken
- Exceptions mit `e_`-Präfix benennen und im Deklarationsteil definieren
- `sqlerrm` und `sqlcode` für Fehlerinformationen nutzen
```sql
declare
e_invalid_status exception;
l_status varchar2(20);
begin
if l_status not in ('COMPLETE', 'INCOMPLETE')
then
raise e_invalid_status;
end if;
exception
when e_invalid_status
then
-- gezielt behandeln
log_error('Ungültiger Status: ' || l_status);
when others
then
-- sqlcode / sqlerrm immer loggen, nie schlucken
log_error(sqlerrm);
raise;
end;
```
---
### Audit-Spalten
Jede Tabelle bekommt am Ende vier Audit-Spalten:
```sql
create table bet_order (
bet_order_id number generated by default as identity not null enable
, ...
,bet_mit_id_angelegt NUMBER(10) not null,
,bet_datum_angelegt DATE not null,
,bet_mit_id_geaendert NUMBER(10) not null,
,bet_datum_geaendert DATE not null,
);
```
Befüllt werden sie über einen `before insert or update`-Trigger pro Tabelle.
Namenskonvention: `trg_<tabellenname>_audit`.
```sql
create or replace editionable trigger trg_fgt_order_audit
before
insert or update on fgt_order
referencing
new as new
old as old
for each row
declare
l_user varchar2(100 byte) := substr(upper(coalesce(
sys_context('apex$session', 'app_user'),
sys_context('userenv', 'os_user'),
sys_context('userenv', 'session_user'))), 1, 100);
l_now date := cast(current_timestamp at time zone 'Europe/Berlin' as date);
begin
if inserting
then
:new.created_at := l_now;
:new.created_by := l_user;
end if;
:new.changed_at := l_now;
:new.changed_by := l_user;
end trg_fgt_order_audit;
```
Der Benutzername wird bevorzugt aus der APEX-Session gelesen, mit Fallback auf OS- bzw. DB-Session-User.
---
### Tabellenänderungen (Migrations-Skripte)
Tabellen können von SQLcl Projects nicht gedropt und neu erstellt werden, wenn sie Daten enthalten.
Änderungen an bestehenden Tabellen werden deshalb als `alter table`-Statements **am Ende der
jeweiligen Tabellendatei** ergänzt — nach dem `create table` und dem Primary-Key-Constraint,
aber **vor** dem `-- sqlcl_snapshot`-Kommentar.
So kann die gesamte Datei als Skript auf eine bestehende Datenbank angewendet werden:
Das `create table` schlägt fehl (Tabelle existiert schon), aber die `alter table`-Statements
laufen durch und bringen die Tabelle auf den aktuellen Stand.
```sql
create table fgt_order ( ... );
alter table fgt_order
add constraint pk_fgt_order primary key (order_id)
using index enable;
-- Migrationsscript — hinzugefügt am 2026-03-30
alter table fgt_order add (
status varchar2(16 char) default 'COMPLETE' not null
,run_id varchar2(36 char)
);
-- sqlcl_snapshot { ... }
```
---
### Planungsdokumente
Für komplexere Features/Packages wird ein Planungsdokument als `.md`-Datei im Projektverzeichnis
abgelegt (z.B. `plan_pck_net_storage.md`). Der Plan wird während der Umsetzung aktuell gehalten —
jede Änderung an Architektur oder Schnittstelle wird sofort im Plan nachgeführt.
---
### Kommentare
- Beschreibungen auf **Deutsch**, Code (außer Fachbegriffe der Anwendungsdomäne) auf **Englisch**
- Block-Kommentar zu Beginn Prozedur/Funktion mit Zweck und Parametern
- Inline-Kommentare mit `--` nur für nicht-offensichtliche Logik
```sql
procedure insert_order (i_json in clob, i_run_id in varchar2)
/*Kopf------------------------------------------------------------------------------------------------
-- Beschreibung: Fügt einen verarbeiteten Auftrag in die Datenbank ein.
------------------------------------------------------------------------------------------------------
-- Parameter: i_json Klippa-Ergebnis als JSON-String
-- i_run_id Ausführungs-Korrelations-ID des Verarbeitungslaufs
------------------------------------------------------------------------------------------------------
-- Rückgabe: <nur bei funktionen, nicht bei procedures>
------------------------------------------------------------------------------------------------------
-- MA Datum Änderung
-- SCK 2026-04-07 Funktion erstellt
------------------------------------------------------------------------------------------------Kopf*/
is
...
```