Skip to content

Commit 456f4e5

Browse files
committed
feat: Add brand manifest policy UI dropdown in Admin
Add UI dropdown in Policies & Workflows section to configure brand_manifest_policy. The brand_manifest_policy system was added in PR #663 with three options: - require_auth (default): Auth required, brand_manifest optional - require_brand: Auth + brand_manifest required (strictest) - public: No auth required, no pricing shown This PR adds the missing UI piece so admins can configure the policy: Changes: - Added dropdown to tenant_settings.html in Policies & Workflows section - Added backend handling in settings.py to save the policy value - Added documentation in docs/brand-manifest-policy.md - Added script to batch update tenants: scripts/update_brand_manifest_policy.py Usage: Admin UI → Tenant Settings → Policies & Workflows → Brand Manifest Policy Related: PR #663 (original implementation)
1 parent cfc1e68 commit 456f4e5

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

src/admin/blueprints/settings.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,20 @@ def update_business_rules(tenant_id):
770770
flash("At least one measurement provider is required.", "error")
771771
return redirect(url_for("tenants.tenant_settings", tenant_id=tenant_id, section="business-rules"))
772772

773+
# Update brand manifest policy
774+
if "brand_manifest_policy" in data:
775+
policy_value = data.get("brand_manifest_policy", "").strip()
776+
if policy_value in ["public", "require_auth", "require_brand"]:
777+
tenant.brand_manifest_policy = policy_value
778+
else:
779+
if request.is_json:
780+
return (
781+
jsonify({"success": False, "error": f"Invalid brand_manifest_policy: {policy_value}"}),
782+
400,
783+
)
784+
flash(f"Invalid brand manifest policy: {policy_value}", "error")
785+
return redirect(url_for("tenants.tenant_settings", tenant_id=tenant_id, section="business-rules"))
786+
773787
# Update approval workflow
774788
if "human_review_required" in data:
775789
manual_approval_value = data.get("human_review_required") in [True, "true", "on", 1, "1"]

templates/tenant_settings.html

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,56 @@ <h3>Budget Controls</h3>
975975
</div>
976976
</div>
977977

978+
<!-- Brand Manifest Policy -->
979+
<div class="form-section">
980+
<h3>Brand Manifest Policy</h3>
981+
<p style="color: #6b7280; font-size: 0.875rem; margin-bottom: 1rem;">
982+
Control when advertisers must provide brand information (<code>brand_manifest</code>) when discovering products or creating campaigns.
983+
</p>
984+
<div class="form-group">
985+
<label for="brand_manifest_policy">Brand Context Requirement</label>
986+
<select id="brand_manifest_policy" name="brand_manifest_policy" class="form-control">
987+
<option value="require_auth" {% if tenant.brand_manifest_policy == 'require_auth' or not tenant.brand_manifest_policy %}selected{% endif %}>
988+
🔐 Require Authentication (brand_manifest optional)
989+
</option>
990+
<option value="require_brand" {% if tenant.brand_manifest_policy == 'require_brand' %}selected{% endif %}>
991+
🔒 Require Authentication + Brand Manifest (strictest)
992+
</option>
993+
<option value="public" {% if tenant.brand_manifest_policy == 'public' %}selected{% endif %}>
994+
🌐 Public (no authentication, no pricing shown)
995+
</option>
996+
</select>
997+
<details style="margin-top: 0.5rem;">
998+
<summary style="cursor: pointer; color: #666; font-size: 0.875rem;">About these options</summary>
999+
<div style="margin-top: 0.5rem; padding: 0.75rem; background: #f8f9fa; border-radius: 4px; font-size: 0.875rem;">
1000+
<p style="margin: 0 0 0.75rem;"><strong>🔐 Require Authentication</strong> (Recommended for most publishers)</p>
1001+
<ul style="margin: 0 0 1rem 1.5rem;">
1002+
<li>Advertisers must authenticate to see products</li>
1003+
<li><code>brand_manifest</code> is <strong>optional</strong></li>
1004+
<li>Pricing shown to authenticated users</li>
1005+
<li>Best for: Standard B2B sales, testing environments</li>
1006+
</ul>
1007+
1008+
<p style="margin: 0 0 0.75rem;"><strong>🔒 Require Authentication + Brand Manifest</strong> (Strictest)</p>
1009+
<ul style="margin: 0 0 1rem 1.5rem;">
1010+
<li>Advertisers must authenticate AND provide brand context</li>
1011+
<li><code>brand_manifest</code> is <strong>required</strong></li>
1012+
<li>Pricing shown only with brand context</li>
1013+
<li>Best for: Bespoke products requiring brand-specific customization</li>
1014+
</ul>
1015+
1016+
<p style="margin: 0 0 0.75rem;"><strong>🌐 Public</strong> (Most open)</p>
1017+
<ul style="margin: 0 0 0; 1.5rem;">
1018+
<li>No authentication required</li>
1019+
<li><code>brand_manifest</code> optional</li>
1020+
<li>Pricing <strong>hidden</strong> (generic catalog only)</li>
1021+
<li>Best for: Public product browsing, lead generation</li>
1022+
</ul>
1023+
</div>
1024+
</details>
1025+
</div>
1026+
</div>
1027+
9781028
<!-- Naming Conventions -->
9791029
<div class="form-section">
9801030
<h3>Naming Conventions</h3>

0 commit comments

Comments
 (0)