MCPcopy Create free account
hub / github.com/adcontextprotocol/adcp / upsertBrandProperties

Method upsertBrandProperties

server/src/crawler.ts:247–318  ·  view source on GitHub ↗

* Extract properties from brand.json and upsert them into the property catalog. * brand.json = "what I own" — the brand declares its properties.

(domain: string, brandJson: Record<string, unknown>)

Source from the content-addressed store, hash-verified

245 * brand.json = "what I own" — the brand declares its properties.
246 */
247 private async upsertBrandProperties(domain: string, brandJson: Record<string, unknown>): Promise<void> {
248 const brands = Array.isArray(brandJson.brands) ? brandJson.brands as Array<Record<string, unknown>> : [];
249 // Also check top-level properties (for simple brand.json without brands array)
250 const topProperties = Array.isArray(brandJson.properties) ? brandJson.properties as Array<Record<string, unknown>> : [];
251
252 const allProperties: Array<{ type: string; identifier: string }> = [];
253 for (const brand of brands) {
254 const props = Array.isArray(brand.properties) ? brand.properties as Array<Record<string, unknown>> : [];
255 for (const p of props) {
256 if (typeof p.identifier === 'string' && typeof p.type === 'string') {
257 allProperties.push({ type: p.type, identifier: p.identifier.toLowerCase() });
258 }
259 }
260 }
261 for (const p of topProperties) {
262 if (typeof p.identifier === 'string' && typeof p.type === 'string') {
263 allProperties.push({ type: p.type, identifier: p.identifier.toLowerCase() });
264 }
265 }
266
267 if (allProperties.length === 0) return;
268
269 // Map brand.json property types to catalog identifier types
270 const typeMap: Record<string, string> = {
271 website: 'domain',
272 mobile_app: 'bundle_id',
273 ctv_app: 'bundle_id',
274 desktop_app: 'bundle_id',
275 dooh: 'domain',
276 podcast: 'domain',
277 radio: 'domain',
278 streaming_audio: 'domain',
279 };
280
281 try {
282 const { uuidv7 } = await import('./db/uuid.js');
283 for (const prop of allProperties) {
284 const identifierType = typeMap[prop.type] || 'domain';
285
286 // Check if this identifier already exists in the catalog
287 const existing = await query<{ property_rid: string }>(
288 'SELECT property_rid FROM catalog_identifiers WHERE identifier_type = $1 AND identifier_value = $2',
289 [identifierType, prop.identifier]
290 );
291
292 if (existing.rows.length > 0) {
293 // Property already in catalog — just update the source timestamp
294 await query(
295 'UPDATE catalog_properties SET source_updated_at = NOW(), updated_at = NOW() WHERE property_rid = $1',
296 [existing.rows[0].property_rid]
297 );
298 } else {
299 // New property — insert into catalog
300 const rid = uuidv7();
301 await query(
302 `INSERT INTO catalog_properties (property_rid, classification, source, status, created_by)
303 VALUES ($1, 'property', 'contributed', 'active', $2)`,
304 [rid, `brand_json:${domain}`]

Callers 1

scanBrandForDomainMethod · 0.95

Calls 3

queryFunction · 0.85
uuidv7Function · 0.85
warnMethod · 0.80

Tested by

no test coverage detected