Promote develop → main (2026-05-17 00:40 UTC) #6
@@ -25,11 +25,13 @@ class TokenResponse(BaseModel):
|
|||||||
class OrgCreate(BaseModel):
|
class OrgCreate(BaseModel):
|
||||||
name: str = Field(min_length=1, max_length=200)
|
name: str = Field(min_length=1, max_length=200)
|
||||||
slug: str = Field(min_length=1, max_length=100, pattern="^[a-z0-9-]+$")
|
slug: str = Field(min_length=1, max_length=100, pattern="^[a-z0-9-]+$")
|
||||||
|
output_language: str = Field(default="de", pattern="^(de|en)$")
|
||||||
|
|
||||||
|
|
||||||
class OrgUpdate(BaseModel):
|
class OrgUpdate(BaseModel):
|
||||||
name: Optional[str] = Field(default=None, max_length=200)
|
name: Optional[str] = Field(default=None, max_length=200)
|
||||||
is_active: Optional[bool] = None
|
is_active: Optional[bool] = None
|
||||||
|
output_language: Optional[str] = Field(default=None, pattern="^(de|en)$")
|
||||||
|
|
||||||
|
|
||||||
class OrgResponse(BaseModel):
|
class OrgResponse(BaseModel):
|
||||||
@@ -43,6 +45,7 @@ class OrgResponse(BaseModel):
|
|||||||
created_at: str
|
created_at: str
|
||||||
globe_access: bool = False
|
globe_access: bool = False
|
||||||
network_access: bool = False
|
network_access: bool = False
|
||||||
|
output_language: str = "de"
|
||||||
|
|
||||||
|
|
||||||
class LicenseCreate(BaseModel):
|
class LicenseCreate(BaseModel):
|
||||||
|
|||||||
@@ -25,6 +25,15 @@ async def _enrich_org(db: aiosqlite.Connection, row: aiosqlite.Row) -> dict:
|
|||||||
lic = await cursor.fetchone()
|
lic = await cursor.fetchone()
|
||||||
org["license_status"] = lic["status"] if lic else "none"
|
org["license_status"] = lic["status"] if lic else "none"
|
||||||
org["license_type"] = lic["license_type"] if lic else ""
|
org["license_type"] = lic["license_type"] if lic else ""
|
||||||
|
|
||||||
|
# output_language aus organization_settings (Default 'de')
|
||||||
|
cursor = await db.execute(
|
||||||
|
"SELECT value FROM organization_settings WHERE organization_id = ? AND key = 'output_language'",
|
||||||
|
(org["id"],),
|
||||||
|
)
|
||||||
|
lang_row = await cursor.fetchone()
|
||||||
|
org["output_language"] = lang_row["value"] if lang_row else "de"
|
||||||
|
|
||||||
return org
|
return org
|
||||||
|
|
||||||
|
|
||||||
@@ -57,6 +66,10 @@ async def create_organization(
|
|||||||
org_id = cursor.lastrowid
|
org_id = cursor.lastrowid
|
||||||
await db.commit()
|
await db.commit()
|
||||||
|
|
||||||
|
# output_language als organization_settings-Eintrag persistieren
|
||||||
|
from shared.services.org_settings import set_org_setting
|
||||||
|
await set_org_setting(db, org_id, "output_language", data.output_language)
|
||||||
|
|
||||||
cursor = await db.execute("SELECT * FROM organizations WHERE id = ?", (org_id,))
|
cursor = await db.execute("SELECT * FROM organizations WHERE id = ?", (org_id,))
|
||||||
new_row_obj = await cursor.fetchone()
|
new_row_obj = await cursor.fetchone()
|
||||||
await log_action(
|
await log_action(
|
||||||
@@ -105,6 +118,11 @@ async def update_organization(
|
|||||||
await db.execute(f"UPDATE organizations SET {set_clause} WHERE id = ?", values)
|
await db.execute(f"UPDATE organizations SET {set_clause} WHERE id = ?", values)
|
||||||
await db.commit()
|
await db.commit()
|
||||||
|
|
||||||
|
# output_language separat ueber organization_settings setzen
|
||||||
|
if data.output_language is not None:
|
||||||
|
from shared.services.org_settings import set_org_setting
|
||||||
|
await set_org_setting(db, org_id, "output_language", data.output_language)
|
||||||
|
|
||||||
after = await row_to_dict(db, "organizations", org_id)
|
after = await row_to_dict(db, "organizations", org_id)
|
||||||
await log_action(
|
await log_action(
|
||||||
db, admin, get_client_ip(request),
|
db, admin, get_client_ip(request),
|
||||||
|
|||||||
@@ -166,6 +166,14 @@
|
|||||||
<option value="false">Deaktiviert</option>
|
<option value="false">Deaktiviert</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editOrgLanguage">Pipeline-Sprache</label>
|
||||||
|
<select id="editOrgLanguage">
|
||||||
|
<option value="de">Deutsch</option>
|
||||||
|
<option value="en">English</option>
|
||||||
|
</select>
|
||||||
|
<small class="text-secondary">Bestimmt die Ausgabesprache der KI (Lagebild, Faktencheck, Recherche) und der sichtbarsten UI-Elemente fuer alle Nutzer dieser Organisation.</small>
|
||||||
|
</div>
|
||||||
<div style="display: flex; gap: 8px; margin-top: 16px;">
|
<div style="display: flex; gap: 8px; margin-top: 16px;">
|
||||||
<button type="submit" class="btn btn-primary">Speichern</button>
|
<button type="submit" class="btn btn-primary">Speichern</button>
|
||||||
<button type="button" class="btn btn-danger" id="deleteOrgBtn">Organisation löschen</button>
|
<button type="button" class="btn btn-danger" id="deleteOrgBtn">Organisation löschen</button>
|
||||||
@@ -499,6 +507,14 @@
|
|||||||
<label for="newOrgSlug">Slug (URL-freundlich)</label>
|
<label for="newOrgSlug">Slug (URL-freundlich)</label>
|
||||||
<input type="text" id="newOrgSlug" required pattern="[a-z0-9-]+" placeholder="z.B. bundespolizei">
|
<input type="text" id="newOrgSlug" required pattern="[a-z0-9-]+" placeholder="z.B. bundespolizei">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="newOrgLanguage">Pipeline-Sprache</label>
|
||||||
|
<select id="newOrgLanguage">
|
||||||
|
<option value="de" selected>Deutsch</option>
|
||||||
|
<option value="en">English</option>
|
||||||
|
</select>
|
||||||
|
<small class="text-secondary">Steuert die Ausgabesprache der KI-Pipeline (Lagebild, Faktencheck, Recherche) und die sichtbarsten UI-Strings im Monitor.</small>
|
||||||
|
</div>
|
||||||
<div id="newOrgError" class="error-msg" style="display:none"></div>
|
<div id="newOrgError" class="error-msg" style="display:none"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
@@ -841,7 +857,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/static/js/app.js?v=20260509j"></script>
|
<script src="/static/js/app.js?v=20260513a"></script>
|
||||||
<script src="/static/js/sources.js?v=20260509d"></script>
|
<script src="/static/js/sources.js?v=20260509d"></script>
|
||||||
<script src="/static/js/source-health.js?v=20260509l"></script>
|
<script src="/static/js/source-health.js?v=20260509l"></script>
|
||||||
<script src="/static/js/audit.js?v=20260509d"></script>
|
<script src="/static/js/audit.js?v=20260509d"></script>
|
||||||
|
|||||||
@@ -213,6 +213,8 @@ async function openOrg(orgId) {
|
|||||||
|
|
||||||
document.getElementById("editOrgName").value = org.name;
|
document.getElementById("editOrgName").value = org.name;
|
||||||
document.getElementById("editOrgActive").value = org.is_active ? "true" : "false";
|
document.getElementById("editOrgActive").value = org.is_active ? "true" : "false";
|
||||||
|
const langEl = document.getElementById("editOrgLanguage");
|
||||||
|
if (langEl) langEl.value = org.output_language || "de";
|
||||||
|
|
||||||
loadOrgUsers(orgId);
|
loadOrgUsers(orgId);
|
||||||
loadOrgLicenses(orgId);
|
loadOrgLicenses(orgId);
|
||||||
@@ -424,6 +426,7 @@ function setupForms() {
|
|||||||
await API.post("/api/orgs", {
|
await API.post("/api/orgs", {
|
||||||
name: document.getElementById("newOrgName").value,
|
name: document.getElementById("newOrgName").value,
|
||||||
slug: document.getElementById("newOrgSlug").value,
|
slug: document.getElementById("newOrgSlug").value,
|
||||||
|
output_language: document.getElementById("newOrgLanguage").value || "de",
|
||||||
});
|
});
|
||||||
closeModal("modalNewOrg");
|
closeModal("modalNewOrg");
|
||||||
document.getElementById("newOrgForm").reset();
|
document.getElementById("newOrgForm").reset();
|
||||||
@@ -518,6 +521,7 @@ function setupForms() {
|
|||||||
await API.put(`/api/orgs/${currentOrgId}`, {
|
await API.put(`/api/orgs/${currentOrgId}`, {
|
||||||
name: document.getElementById("editOrgName").value,
|
name: document.getElementById("editOrgName").value,
|
||||||
is_active: document.getElementById("editOrgActive").value === "true",
|
is_active: document.getElementById("editOrgActive").value === "true",
|
||||||
|
output_language: document.getElementById("editOrgLanguage").value || "de",
|
||||||
});
|
});
|
||||||
openOrg(currentOrgId);
|
openOrg(currentOrgId);
|
||||||
loadOrgs();
|
loadOrgs();
|
||||||
|
|||||||
In neuem Issue referenzieren
Einen Benutzer sperren