@prefix : <https://ontology.inferal.com/modules/advertising-entity/> .
@prefix adm: <https://ontology.inferal.com/modules/advertising-measurement/> .
@prefix ci: <https://ontology.inferal.com/modules/company-intelligence/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix mod: <https://w3id.org/mod#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix pubacc: <https://ontology.inferal.com/modules/publication-access/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix vann: <http://purl.org/vocab/vann/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

:
    a owl:Ontology, pubacc:PublicationManagedOntology ;
    dcterms:accessRights pubacc:PublicAccess ;
    owl:imports
        adm: ,
        ci: ,
        <http://www.w3.org/2004/02/skos/core> ,
        <http://www.w3.org/ns/prov> ;
    dcterms:title "Advertising Entity Ontology" ;
    dcterms:description "The tiers an advertiser configures: accounts held by parties at a channel, campaigns carrying objective and budget scope, targeting groups carrying audience and bid, ads that deliver, and the creatives they carry." ;
    dcterms:license <https://creativecommons.org/licenses/by/4.0/> ;
    dcterms:source adm: , ci: , <http://www.w3.org/2004/02/skos/core> , <http://www.w3.org/ns/prov> ;
    vann:preferredNamespacePrefix "aent" ;
    vann:preferredNamespaceUri "https://ontology.inferal.com/modules/advertising-entity/" ;
    mod:status "draft" ;
    rdfs:comment "Each tier is named for what it carries rather than for the word a provider happens to use, because the words disagree and the functions do not. One provider's campaign is another's campaign group, and the tier carrying targeting and bid is called a campaign on one platform and an ad set on another. Naming by function is what makes those mappings ordinary instead of surprising, and it removes the reading that a middle tier is a group of ads: it is the tier at which audience and bid are set, and it contains ads as a consequence rather than as its definition. Containment is not defined here. It is reified with a validity interval in the measurement module, so an entity that moves between parents does not silently rewrite the hierarchy its past metrics were measured under. Identity is not a bare string either: an identifier means nothing without the platform it came from, and platforms reuse numeric ranges freely." ;
    owl:versionInfo "0.1.0" .


# --- Tiers -------------------------------------------------------------------

:AdvertisingResource
    a rdfs:Class ;
    rdfs:subClassOf prov:Entity ;
    rdfs:label "advertising resource" ;
    rdfs:comment "Anything an advertiser configures or produces: the tiers of an account hierarchy, and the creatives those tiers deliver." ;
    dcterms:description "Exists because naming and provenance are common to both while position in the hierarchy is not. Configured tiers require provider identity. A creative may also have one when the provider exposes a distinct asset identifier, but a folded provider record may expose only the ad identity; a projection must not invent a second provider identity merely to split the asset honestly." .

:AdvertisingEntity
    a rdfs:Class ;
    rdfs:subClassOf :AdvertisingResource ;
    rdfs:label "advertising entity" ;
    rdfs:comment "Anything an advertiser configures on a platform and can be measured against: an account, a campaign, a targeting group, or an ad." ;
    dcterms:description "The common parent exists so measurement, budgets, and delivery state can refer to a configured thing without naming a tier. It is deliberately not a taxonomy root for everything advertising: a creative is not one of these, because a creative is an asset rather than a configured position in a hierarchy." .

:AdAccount
    a rdfs:Class ;
    rdfs:subClassOf :AdvertisingEntity ;
    rdfs:label "ad account" ;
    rdfs:comment "An account at one advertising channel, held by a party, under which campaigns are configured and spend is billed." ;
    dcterms:description "An account is not the organisation that holds it. An agency holds accounts for several clients and a client moves between agencies, so the holder is stated as a time-bounded role rather than by making the account a kind of organisation. The account carries the currency and the billing relationship; the party carries the identity." ;
    skos:altLabel "advertiser account" ;
    skos:hiddenLabel "customer", "ad account" .

:Campaign
    a rdfs:Class ;
    rdfs:subClassOf :AdvertisingEntity ;
    rdfs:label "advertising campaign" ;
    rdfs:comment "The tier at which an advertising objective and the budget scope that funds it are configured, when the provider exposes those facts. Named in full because a campaign in general is not an advertising campaign: military, political, and fundraising campaigns are all campaigns, and the last two may contain advertising campaigns without being them." ;
    dcterms:description "Named for its role, which is why one provider's campaign group maps here while that provider's campaign does not. Objective and budget scope distinguish the tier in a complete provider model, but a source record may omit either fact. Absence means unreported and is never evidence for an invented unknown value or for reclassifying the resource by its provider label." ;
    skos:altLabel "campaign", "campaign group" ;
    skos:hiddenLabel "campaign", "campaign_group" .

:TargetingGroup
    a rdfs:Class ;
    rdfs:subClassOf :AdvertisingEntity ;
    rdfs:label "targeting group" ;
    rdfs:comment "The tier carrying the audience an advertiser wants to reach and the bid it will pay to reach them. It contains ads as a consequence of sitting at that tier, not as its definition." ;
    dcterms:description "Deliberately not named for any provider's word. One platform calls this an ad set, another an ad group, and a third calls it a campaign while calling the budget tier a campaign group. A name built from ad and group invites the reading that the tier is a group of ads, which is the reading that breaks the mapping: the tier is where targeting and bid are set, and a provider that sets them on something it calls a campaign has that campaign land here." ;
    skos:altLabel "ad group", "ad set" ;
    skos:hiddenLabel "adset", "ad_group", "adgroup", "campaign" .

:Ad
    a rdfs:Class ;
    rdfs:subClassOf :AdvertisingEntity ;
    rdfs:label "ad" ;
    rdfs:comment "A configured delivery unit pairing a creative with the targeting group that decides who sees it." ;
    dcterms:description "The ad is the configuration, not the artwork. Two ads in different targeting groups may carry one creative, and their impressions are separate while the creative is one thing. One provider already models this split, pairing an ad-group ad with a reusable creative." ;
    skos:hiddenLabel "ad", "ad_group_ad" .

:Creative
    a rdfs:Class ;
    rdfs:subClassOf :AdvertisingResource ;
    rdfs:label "creative" ;
    rdfs:comment "The asset an ad delivers: the copy, imagery, video, and call to action a person actually sees." ;
    dcterms:description "Not an advertising entity, because it occupies no position in the account hierarchy and is not configured against an audience. It is reusable across ads, which is the distinction the folded form loses: a creative used by six ads is one creative with six placements of it, and counting it six times overstates how much was made. When a provider exposes only a folded ad-and-creative identifier, the creative remains a stable, provenanced IRI without a fabricated provider identity." ;
    skos:hiddenLabel "creative", "ad_creative" .


# --- Identity ----------------------------------------------------------------

:ProviderIdentity
    a rdfs:Class ;
    rdfs:label "provider identity" ;
    rdfs:comment "An identifier an entity carries on one channel, paired with the channel that issued it." ;
    dcterms:description "An identifier alone does not identify. Platforms reuse numeric ranges freely, one provider's identifiers are opaque resource paths and another's are integers, and the same entity carries different identifiers on different platforms when a measurement vendor reports on it. Pairing the value with its channel is what makes a join sound; putting several identifier spaces on one shared predicate, which is what the vocabulary this module replaces does, makes a join on it conflate unrelated entities." .


# --- Objectives --------------------------------------------------------------

:CreativeFormat
    a rdfs:Class ;
    rdfs:subClassOf skos:Concept ;
    rdfs:label "creative format" ;
    rdfs:comment "The presentational form an asset takes, such as a single image, a carousel of several, or a video." ;
    dcterms:description "A concept rather than a string because format determines which metrics apply: video view counts are meaningless for a static image, and providers name the same forms differently. Profiles extend the scheme." .

:Objective
    a rdfs:Class ;
    rdfs:subClassOf skos:Concept ;
    rdfs:label "advertising objective" ;
    rdfs:comment "The outcome an advertising campaign is optimised toward, such as awareness, traffic, or sales. Named in full because an objective in general belongs to no domain in particular." ;
    dcterms:description "A concept rather than a string because objectives determine which metrics are meaningful: an awareness campaign judged on conversions is being judged on the wrong thing. Providers each ship their own list, so profiles extend this scheme." ;
    skos:altLabel "objective" .


:BidStrategy
    a rdfs:Class ;
    rdfs:subClassOf skos:Concept ;
    rdfs:label "advertising bid strategy" ;
    skos:altLabel "bid strategy" ;
    rdfs:comment "The rule a campaign bids under, such as maximising outcomes or holding to a cost or return target." ;
    dcterms:description "Distinct from the bid amount set on the targeting tier: the strategy says what the amount means, and a figure bid under a cost target is not comparable with one bid under a return target. Two providers set it on the campaign and apply it to every targeting group beneath, which is why it sits at this tier." .


# --- Object properties -------------------------------------------------------

:identifiedBy
    a rdf:Property ;
    rdfs:label "identified by" ;
    rdfs:comment "A provider identity this entity carries. Repeatable, because one entity may be identified differently on the platform that runs it and on a measurement platform that reports it." ;
    rdfs:domain :AdvertisingResource ;
    rdfs:range :ProviderIdentity .

:issuingChannel
    a rdf:Property ;
    rdfs:label "issuing channel" ;
    rdfs:comment "The channel that issued this identifier, without which the value does not identify anything." ;
    rdfs:domain :ProviderIdentity ;
    rdfs:range adm:Channel .

:heldUnderRole
    a rdf:Property ;
    rdfs:label "held under role" ;
    rdfs:comment "The role under which a party holds this account, stated as a time-bounded relationship rather than by conflating the account with its holder." ;
    rdfs:domain :AdAccount ;
    rdfs:range ci:Role .

:accountChannel
    a rdf:Property ;
    rdfs:label "account channel" ;
    rdfs:comment "The advertising channel this account exists at." ;
    rdfs:domain :AdAccount ;
    rdfs:range adm:Channel .

:pursuesObjective
    a rdf:Property ;
    rdfs:label "pursues objective" ;
    rdfs:comment "The outcome this campaign is optimised toward, when the source reports one. Absence means unreported rather than unknown." ;
    rdfs:domain :Campaign ;
    rdfs:range :Objective .

:carriesTargeting
    a rdf:Property ;
    rdfs:label "carries targeting" ;
    rdfs:comment "The audience specification this tier delivers against. Left deliberately unstructured: two providers ship targeting as an untyped blob, so describing its internals here would make their data unrepresentable." ;
    dcterms:description "This property and the bid are what make the tier the targeting tier. Without them the class asserts in prose that it carries targeting and bid while carrying neither, which is the same defect as naming a tier for a word: the definition has to be load-bearing rather than decorative." ;
    rdfs:domain :TargetingGroup ;
    rdfs:range rdfs:Resource .

:bidAmount
    a rdf:Property ;
    rdfs:label "bid amount" ;
    rdfs:comment "The amount this tier will pay for the outcome it bids on, reusing the shared monetary amount so a bid and the spend it produces are denominated in the same terms." ;
    dcterms:description "Set at this tier on every provider, which is part of what identifies the tier. One provider ships it as a minor-unit string and another as a money object; both lower to the shared amount." ;
    rdfs:domain :TargetingGroup ;
    rdfs:range adm:MonetaryAmount .

:pursuesBidStrategy
    a rdf:Property ;
    rdfs:label "pursues bid strategy" ;
    rdfs:comment "The bidding rule this campaign applies, when the source reports one." ;
    dcterms:description "Optional because a provider may not report it. Absence means unreported and never implies manual bidding." ;
    rdfs:domain :Campaign ;
    rdfs:range :BidStrategy .


:creativeFormat
    a rdf:Property ;
    rdfs:label "has creative format" ;
    rdfs:comment "The presentational form of the asset, such as a single image, a carousel, or a video." ;
    dcterms:description "The one intrinsic property the creative carries here. Without it the class is a marker distinguishable from a label only by its comment, and a consumer asking which video creatives performed best has nowhere to look." ;
    rdfs:domain :Creative ;
    rdfs:range :CreativeFormat .

:deliversCreative
    a rdf:Property ;
    rdfs:label "delivers creative" ;
    rdfs:comment "The asset this ad delivers. Several ads may deliver one creative, which is why the two are separate resources." ;
    rdfs:domain :Ad ;
    rdfs:range :Creative .


# --- Datatype properties -----------------------------------------------------

:identifierValue
    a rdf:Property ;
    rdfs:label "identifier value" ;
    rdfs:comment "The identifier as the issuing channel states it, preserved verbatim. Providers ship integers, opaque resource paths, and prefixed strings, and normalising them would lose the ability to address the entity on its own platform." ;
    rdfs:domain :ProviderIdentity ;
    rdfs:range xsd:string .

:entityName
    a rdf:Property ;
    rdfs:label "entity name" ;
    rdfs:comment "The advertiser's own name for this entity. Names are not identifiers: they are edited freely, repeat across accounts, and are absent on some tiers." ;
    rdfs:domain :AdvertisingResource ;
    rdfs:range xsd:string .

:accountCurrency
    a rdf:Property ;
    rdfs:label "account currency" ;
    rdfs:comment "The ISO 4217 code of the currency this account is billed and reported in. Metrics rows generally omit it, so it is resolved from here." ;
    rdfs:domain :AdAccount ;
    rdfs:range xsd:string .


# --- Objective scheme --------------------------------------------------------

:ObjectiveScheme
    a skos:ConceptScheme ;
    rdfs:label "objective scheme" ;
    rdfs:comment "Cross-provider anchors for campaign objectives. Provider profiles extend this scheme rather than defining parallel classes." ;
    skos:prefLabel "Advertising objectives" .

:awarenessObjective
    a :Objective, skos:Concept ;
    skos:inScheme :ObjectiveScheme ;
    rdfs:label "awareness" ;
    rdfs:comment "Optimised toward being seen by as many relevant people as possible. Judged on reach and frequency rather than on clicks or conversions." .

:trafficObjective
    a :Objective, skos:Concept ;
    skos:inScheme :ObjectiveScheme ;
    rdfs:label "traffic" ;
    rdfs:comment "Optimised toward sending people to a destination. Judged on clicks and cost per click." .

:engagementObjective
    a :Objective, skos:Concept ;
    skos:inScheme :ObjectiveScheme ;
    rdfs:label "engagement objective" ;
    rdfs:comment "Optimised toward interactions with the ad or its surrounding content." .

:leadObjective
    a :Objective, skos:Concept ;
    skos:inScheme :ObjectiveScheme ;
    rdfs:label "leads" ;
    rdfs:comment "Optimised toward collecting contact details or expressions of interest." .

:salesObjective
    a :Objective, skos:Concept ;
    skos:inScheme :ObjectiveScheme ;
    rdfs:label "sales" ;
    rdfs:comment "Optimised toward purchases or other revenue-bearing outcomes. The only objective for which a return figure is straightforwardly meaningful." .

:appPromotionObjective
    a :Objective, skos:Concept ;
    skos:inScheme :ObjectiveScheme ;
    rdfs:label "app promotion" ;
    rdfs:comment "Optimised toward installs or in-app activity." .


# --- Bid strategy scheme -----------------------------------------------------

:BidStrategyScheme
    a skos:ConceptScheme ;
    rdfs:label "bid strategy scheme" ;
    rdfs:comment "Cross-provider anchors for campaign bidding rules. Provider profiles extend this scheme rather than defining parallel classes." ;
    skos:prefLabel "Advertising bid strategies" .

:maximiseOutcomesStrategy
    a :BidStrategy, skos:Concept ;
    skos:inScheme :BidStrategyScheme ;
    rdfs:label "maximise outcomes" ;
    rdfs:comment "Spend the budget to obtain as many outcomes as possible, with no cost or return target stated." .

:costTargetStrategy
    a :BidStrategy, skos:Concept ;
    skos:inScheme :BidStrategyScheme ;
    rdfs:label "cost target" ;
    rdfs:comment "Bid so that the average cost of an outcome holds to a stated figure." .

:valueTargetStrategy
    a :BidStrategy, skos:Concept ;
    skos:inScheme :BidStrategyScheme ;
    rdfs:label "value target" ;
    rdfs:comment "Bid so that the return on spend holds to or exceeds a stated ratio." .


# --- Creative format scheme --------------------------------------------------

:CreativeFormatScheme
    a skos:ConceptScheme ;
    rdfs:label "creative format scheme" ;
    rdfs:comment "Cross-provider anchors for creative formats. Provider profiles extend this scheme." ;
    skos:prefLabel "Creative formats" .

:singleImageFormat
    a :CreativeFormat, skos:Concept ;
    skos:inScheme :CreativeFormatScheme ;
    rdfs:label "single image" ;
    rdfs:comment "One static image with accompanying copy." .

:carouselFormat
    a :CreativeFormat, skos:Concept ;
    skos:inScheme :CreativeFormatScheme ;
    rdfs:label "carousel" ;
    rdfs:comment "Several cards a person swipes through, each with its own destination." .

:videoFormat
    a :CreativeFormat, skos:Concept ;
    skos:inScheme :CreativeFormatScheme ;
    rdfs:label "video creative format" ;
    rdfs:comment "Moving image with optional sound. The only format for which video view metrics are meaningful." .

:collectionFormat
    a :CreativeFormat, skos:Concept ;
    skos:inScheme :CreativeFormatScheme ;
    rdfs:label "collection" ;
    rdfs:comment "A cover asset above a grid of products, opening into a full-screen experience." .
