## Turtle Start ##
@prefix schema:    <http://schema.org/> .
@prefix xsd:       <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs:      <http://www.w3.org/2000/01/rdf-schema#> .
@prefix wdrs:      <http://www.w3.org/2007/05/powder-s#> .
@prefix foaf:      <http://xmlns.com/foaf/0.1/> .
@prefix acl:       <http://www.w3.org/ns/auth/acl#> .
@prefix filter:    <http://www.openlinksw.com/schemas/acl/filter#> .
@prefix oplacl:    <http://www.openlinksw.com/ontology/acl#> .
@prefix oplres:    <http://www.openlinksw.com/ontology/restrictions#> .
@prefix oplofr:    <http://www.openlinksw.com/ontology/offers#> .
@prefix source:    <http://virtuoso.openlinksw.com/data/turtle/Offers-authorizatoins-and-restrictions.ttl> .

# --- Document Metadata ---

source: a schema:CreativeWork ;
    schema:name "OPAL, Graph, and File Access Authorization, Groups and Restrictions Definitions" ;
    schema:comment "This document describes the rules, groups and restrictions required for the OPAL and graph access offers." ;
    schema:author <http://www.openlinksw.com/#this> ;
    schema:datePublished "2026-01-14T00:00:00Z"^^xsd:dateTime .

# --- Offer Groups ---

<http://data.openlinksw.com/oplweb/OfferGroupChatService#this> a oplofr:OfferGroup ;
    schema:name "OPAL Chat Service Offers" ;
    rdfs:label "OPAL Chat Service Offers" .

<http://data.openlinksw.com/oplweb/OfferGroupApiAccess#this> a oplofr:OfferGroup ;
    schema:name "OPAL API Access Offers" ;
    rdfs:label "OPAL API Access Offers" ;
    schema:description "Offers for sessions instantiated via the /chat/api endpoints." .

<http://data.openlinksw.com/oplweb/OfferGroupGraphAccess#this> a oplofr:OfferGroup ;
    schema:name "Specific Knowledge Graph Access Offers" ;
    rdfs:label "Specific Knowledge Graph Access Offers" .

<http://data.openlinksw.com/oplweb/OfferGroupFileAccess#this> a oplofr:OfferGroup ;
    schema:name "Specific Knowledge File Access Offers" ;
    rdfs:label "Specific Knowledge File Access Offers" .

## --- Opal Chat Access ---
# ==============================================================================
# Conditonal Group Definitions for each offer type
# ==============================================================================

<http://data.openlinksw.com/oplweb/group/DataTwinglerEntryLevelSpecificChatUsers#this> a oplacl:ConditionalGroup ;
  foaf:name "OPAL Users identified using a NetID based Identifier who have purchased the Data Twingler Assistant offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
        union
        { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
        graph ?cg {
          { ^{uri}^ oplprchs:madePurchase ?purchase . }
          union
          { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
          ?purchase oplprchs:contains ?offer ;
                    oplprchs:purchaseDate ?purchaseDate .
          ?offer a oplofr:DataTwinglerSpecificModuleEntryLevelOffer ;
                 schema:itemOffered ?license .
          ?license opllic:hasDuration ?duration .
          ?duration opllic:durationYears ?years .
          filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
        }
      }"""
     ] .

<http://data.openlinksw.com/oplweb/group/DataTwinglerPlusSpecificChatUsers#this> a oplacl:ConditionalGroup ;
  foaf:name "OPAL Users identified using a NetID based Identifier who have purchased the Data Twingler Assistant offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        {
          select ?license where {
            { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
            union
            { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
            graph ?cg {
              { ^{uri}^ oplprchs:madePurchase ?purchase . }
              union
              { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
              ?purchase oplprchs:contains ?offer ;
                        oplprchs:purchaseDate ?purchaseDate .
              ?offer a oplofr:DataTwinglerSpecificModulePlusOffer ;
                     schema:itemOffered ?license .
              ?license opllic:hasDuration ?duration .
              ?duration opllic:durationYears ?years .
              filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
            }
          } limit 1
        }
        filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
      }"""
     ] .

<http://data.openlinksw.com/oplweb/group/DataTwinglerProSpecificChatUsers#this> a oplacl:ConditionalGroup ;
  foaf:name "OPAL Users identified using a NetID based Identifier who have purchased the Data Twingler Assistant offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        {
          select ?license where {
            { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
            union
            { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
            graph ?cg {
              { ^{uri}^ oplprchs:madePurchase ?purchase . }
              union
              { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
              ?purchase oplprchs:contains ?offer ;
                        oplprchs:purchaseDate ?purchaseDate .
              ?offer a oplofr:DataTwinglerSpecificModuleProOffer ;
                     schema:itemOffered ?license .
              ?license opllic:hasDuration ?duration .
              ?duration opllic:durationYears ?years .
              filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
            }
          } limit 1
        }
        filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
      }"""
     ] .

<http://data.openlinksw.com/oplweb/group/DataTwinglerMaxSpecificChatUsers#this> a oplacl:ConditionalGroup ;
  foaf:name "OPAL Users identified using a NetID based Identifier who have purchased the Data Twingler Assistant offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        {
          select ?license where {
            { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
            union
            { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
            graph ?cg {
              { ^{uri}^ oplprchs:madePurchase ?purchase . }
              union
              { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
              ?purchase oplprchs:contains ?offer ;
                        oplprchs:purchaseDate ?purchaseDate .
              ?offer a oplofr:DataTwinglerSpecificModuleMaxOffer ;
                     schema:itemOffered ?license .
              ?license opllic:hasDuration ?duration .
              ?duration opllic:durationYears ?years .
              filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
            }
          } limit 1
        }
        filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
      }"""
     ] .

<http://data.openlinksw.com/oplweb/group/SupportAssistantEntryLevelSpecificChatUsers#this> a oplacl:ConditionalGroup ;
  foaf:name "OPAL Users identified using a NetID based Identifier who have purchased the Data Twingler Assistant offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
        union
        { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
        graph ?cg {
          { ^{uri}^ oplprchs:madePurchase ?purchase . }
          union
          { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
          ?purchase oplprchs:contains ?offer ;
                    oplprchs:purchaseDate ?purchaseDate .
          ?offer a oplofr:SupportAssistantSpecificModuleEntryLevelOffer ;
                 schema:itemOffered ?license .
          ?license opllic:hasDuration ?duration .
          ?duration opllic:durationYears ?years .
          filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
        }
      }"""
     ] .

<http://data.openlinksw.com/oplweb/group/SupportAssistantPlusSpecificChatUsers#this> a oplacl:ConditionalGroup ;
  foaf:name "OPAL Users identified using a NetID based Identifier who have purchased the Data Twingler Assistant offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        {
          select ?license where {
            { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
            union
            { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
            graph ?cg {
              { ^{uri}^ oplprchs:madePurchase ?purchase . }
              union
              { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
              ?purchase oplprchs:contains ?offer ;
                        oplprchs:purchaseDate ?purchaseDate .
              ?offer a oplofr:SupportAssistantSpecificModulePlusOffer ;
                     schema:itemOffered ?license .
              ?license opllic:hasDuration ?duration .
              ?duration opllic:durationYears ?years .
              filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
            }
          } limit 1
        }
        filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
      }"""
     ] .

<http://data.openlinksw.com/oplweb/group/SupportAssistantProSpecificChatUsers#this> a oplacl:ConditionalGroup ;
  foaf:name "OPAL Users identified using a NetID based Identifier who have purchased the Data Twingler Assistant offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        {
          select ?license where {
            { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
            union
            { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
            graph ?cg {
              { ^{uri}^ oplprchs:madePurchase ?purchase . }
              union
              { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
              ?purchase oplprchs:contains ?offer ;
                        oplprchs:purchaseDate ?purchaseDate .
              ?offer a oplofr:SupportAssistantSpecificModuleProOffer ;
                     schema:itemOffered ?license .
              ?license opllic:hasDuration ?duration .
              ?duration opllic:durationYears ?years .
              filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
            }
          } limit 1
        }
        filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
      }"""
     ] .

<http://data.openlinksw.com/oplweb/group/SupportAssistantMaxSpecificChatUsers#this> a oplacl:ConditionalGroup ;
  foaf:name "OPAL Users identified using a NetID based Identifier who have purchased access to the Support Assistant chat offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        {
          select ?license where {
            { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
            union
            { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
            graph ?cg {
              { ^{uri}^ oplprchs:madePurchase ?purchase . }
              union
              { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
              ?purchase oplprchs:contains ?offer ;
                        oplprchs:purchaseDate ?purchaseDate .
              ?offer a oplofr:SupportAssistantSpecificModuleMaxOffer ;
                     schema:itemOffered ?license .
              ?license opllic:hasDuration ?duration .
              ?duration opllic:durationYears ?years .
              filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
            }
          } limit 1
        }
        filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
      }"""
     ] .

<http://data.openlinksw.com/oplweb/group/BringYourOwnKeyEntryLevelUsers#this> a oplacl:ConditionalGroup ;
  foaf:name "OPAL Users identified using a NetID based Identifier who have purchased the Entry level offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
        union
        { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
        graph ?cg {
          { ^{uri}^ oplprchs:madePurchase ?purchase . }
          union
          { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
          ?purchase oplprchs:contains ?offer ;
                    oplprchs:purchaseDate ?purchaseDate .
          ?offer a oplofr:BringYourOwnKeyEntryLevelOffer ;
                 schema:itemOffered ?license .
          ?license opllic:hasDuration ?duration .
          ?duration opllic:durationYears ?years .
          filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
        }
      }"""
     ] .

<http://data.openlinksw.com/oplweb/group/BringYourOwnKeyPlusUsers#this> a oplacl:ConditionalGroup ;
  foaf:name "OPAL Users identified using a NetID based Identifier who have purchased the Plus level offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        {
          select ?license where {
            { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
            union
            { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
            graph ?cg {
              { ^{uri}^ oplprchs:madePurchase ?purchase . }
              union
              { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
              ?purchase oplprchs:contains ?offer ;
                        oplprchs:purchaseDate ?purchaseDate .
              ?offer a oplofr:BringYourOwnKeyPlusOffer ;
                     schema:itemOffered ?license .
              ?license opllic:hasDuration ?duration .
              ?duration opllic:durationYears ?years .
              filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
            }
          } limit 1
        }
        filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
      }"""
     ] .

<http://data.openlinksw.com/oplweb/group/BringYourOwnKeyProUsers#this> a oplacl:ConditionalGroup ;
  foaf:name "OPAL Users identified using a NetID based Identifier who have purchased the Pro level offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        {
          select ?license where {
            { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
            union
            { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
            graph ?cg {
              { ^{uri}^ oplprchs:madePurchase ?purchase . }
              union
              { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
              ?purchase oplprchs:contains ?offer ;
                        oplprchs:purchaseDate ?purchaseDate .
              ?offer a oplofr:BringYourOwnKeyProOffer ;
                     schema:itemOffered ?license .
              ?license opllic:hasDuration ?duration .
              ?duration opllic:durationYears ?years .
              filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
            }
          } limit 1
        }
        filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
      }"""
     ] .

<http://data.openlinksw.com/oplweb/group/MaxUsers#this> a oplacl:ConditionalGroup ;
  foaf:name "OPAL Users identified using a NetID based Identifier who have purchased the Max level offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        {
          select ?license where {
            { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
            union
            { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
            graph ?cg {
              { ^{uri}^ oplprchs:madePurchase ?purchase . }
              union
              { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
              ?purchase oplprchs:contains ?offer ;
                        oplprchs:purchaseDate ?purchaseDate .
              ?offer a oplofr:MaxOffer ;
                     schema:itemOffered ?license .
              ?license opllic:hasDuration ?duration .
              ?duration opllic:durationYears ?years .
              filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
            }
          } limit 1
        }
        filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
      }"""
     ] .

# ==============================================================================
# Restrictions
# ==============================================================================

# ------------------------------------------------------------------------------
# A. Session & Token Limits
# ------------------------------------------------------------------------------

# --- Entry Level Limits ---

# Max Prompts per session : 20
# Max Input Tokens per prompt: 2,000
# Max Total Tokens per session: 4,000
# Rate limit per hour: 1500 (25 per minute)

oplres:max-prompt-count-per-session a oplres:Restriction ;
  schema:name "Max prompts per session" ;
  schema:description "Users are limited to a maximum of 20 prompts within a single session" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-prompts> ;
  oplres:hasMaxValue "20"^^xsd:decimal ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerEntryLevelSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantEntryLevelSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyEntryLevelUsers#this> ;
  wdrs:describedby <#source> .

oplres:max-token-usage-per-prompt a oplres:Restriction ;
  schema:name "Max tokens per prompt" ;
  schema:description "Each prompt can use up to 2000 tokens" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-prompt-tokens> ;
  oplres:hasMaxValue "2000"^^xsd:decimal ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerEntryLevelSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantEntryLevelSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyEntryLevelUsers#this> ;
  wdrs:describedby <#source> .

oplres:max-total-token-usage-per-session a oplres:Restriction ;
  schema:name "Max total tokens per session" ;
  schema:description "The total token usage for an entire session is capped at 4000 tokens" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-tokens> ;
  oplres:hasMaxValue "4000"^^xsd:decimal ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerEntryLevelSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantEntryLevelSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyEntryLevelUsers#this> ;
  wdrs:describedby <#source> .

oplres:max-prompt-interval-count-entry a oplres:Restriction ;
  schema:name "Max 25 prompts for min" ;
  schema:description "Up to 25 prompts" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-prompts-interval-count> ;
  oplres:hasMaxValue "1500"^^xsd:int ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerEntryLevelSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantEntryLevelSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyEntryLevelUsers#this> ;
  wdrs:describedby <#source> .


### Average prompts for interval of 1h

oplres:max-prompt-interval-1h a oplres:Restriction ;
  schema:name "Interval of 1 hour" ;
  schema:description "Interval used for all limits" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-prompts-interval> ;
  oplres:hasMaxValue "3600"^^xsd:int ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgentClass foaf:Agent ;
  wdrs:describedby <#source> .

# --- Plus Level Limits ---

# Max Prompts per session: 200
# Max Input Tokens per prompt: 20,000
# Max Total Tokens per session: 40,000
# Rate limit per hour: 15000 (250 per minute)

oplres:max-prompt-count-per-session-plus-offer a oplres:Restriction ;
  schema:name "Max prompts per session" ;
  schema:description "Users are limited to a maximum of 200 prompts within a single session" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-prompts> ;
  oplres:hasMaxValue "200"^^xsd:decimal ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyPlusUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerPlusSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantPlusSpecificChatUsers#this> ;
  wdrs:describedby <#source> .

oplres:max-token-usage-per-prompti-plus-offer a oplres:Restriction ;
  schema:name "Max tokens per prompt" ;
  schema:description "Each prompt can use up to 20000 tokens" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-prompt-tokens> ;
  oplres:hasMaxValue "20000"^^xsd:decimal ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyPlusUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerPlusSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantPlusSpecificChatUsers#this> ;
  wdrs:describedby <#source> .

oplres:max-total-token-usage-per-session-plus-offer a oplres:Restriction ;
  schema:name "Max total tokens per session" ;
  schema:description "The total token usage for an entire session is capped at 40000 tokens" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-tokens> ;
  oplres:hasMaxValue "40000"^^xsd:decimal ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyPlusUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerPlusSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantPlusSpecificChatUsers#this> ;
  wdrs:describedby <#source> .

oplres:max-prompt-interval-count-plus a oplres:Restriction ;
  schema:name "Max 250 prompts for interval 1 min" ;
  schema:description "Up to 250 prompts" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-prompts-interval-count> ;
  oplres:hasMaxValue "15000"^^xsd:int ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerPlusSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantPlusSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyPlusUsers#this> ;
  wdrs:describedby <#source> .

# --- Pro Level Limits ---

# Max Prompts: 400
# Max Input Tokens: 100,000
# Max Total Tokens: 200,000
# Rate limit per hour: 30000 (500 per minute)

oplres:max-prompt-count-per-session-pro-offer a oplres:Restriction ;
  schema:name "Max prompts per session" ;
  schema:description "Users are limited to a maximum of 400 prompts within a single session" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-prompts> ;
  oplres:hasMaxValue "400"^^xsd:decimal ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyProUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerProSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantProSpecificChatUsers#this> ;
  wdrs:describedby <#source> .

oplres:max-token-usage-per-prompt-pro-offer a oplres:Restriction ;
  schema:name "Max tokens per prompt" ;
  schema:description "Each prompt can use up to 100k tokens" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-prompt-tokens> ;
  oplres:hasMaxValue "100000"^^xsd:decimal ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyProUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerProSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantProSpecificChatUsers#this> ;
  wdrs:describedby <#source> .

oplres:max-total-token-usage-per-session-pro-offer a oplres:Restriction ;
  schema:name "Max total tokens per session" ;
  schema:description "The total token usage for an entire session is capped at 200k tokens" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-tokens> ;
  oplres:hasMaxValue "200000"^^xsd:decimal ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyProUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerProSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantProSpecificChatUsers#this> ;
  wdrs:describedby <#source> .

oplres:max-prompt-interval-count-pro a oplres:Restriction ;
  schema:name "Max 500 prompts for interval 1 min" ;
  schema:description "Up to 500 prompts" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-prompts-interval-count> ;
  oplres:hasMaxValue "3000"^^xsd:int ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerProSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantProSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyProUsers#this> ;
  wdrs:describedby <#source> .

# --- Max Level Limits ---

# Max Prompts per session: 1,000
# Max Input Tokens per prompt: 500,000
# Max Total Tokens per session: 1,000,000
# Rate limit per hour: 60000 (1000 per minute)
oplres:max-prompt-count-per-session-max-offer a oplres:Restriction ;
  schema:name "Max prompts per session" ;
  schema:description "Users are limited to a maximum of 1k prompts within a single session" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-prompts> ;
  oplres:hasMaxValue "1000"^^xsd:decimal ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/MaxUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantMaxSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerMaxSpecificChatUsers#this> ;
  wdrs:describedby <#source> .

oplres:max-token-usage-per-prompt-max-offer a oplres:Restriction ;
  schema:name "Max tokens per prompt" ;
  schema:description "Each prompt can use up to 500k tokens" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-prompt-tokens> ;
  oplres:hasMaxValue "500000"^^xsd:decimal ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/MaxUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantMaxSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerMaxSpecificChatUsers#this> ;
  wdrs:describedby <#source> .

oplres:max-total-token-usage-per-session-max-offer a oplres:Restriction ;
  schema:name "Max total tokens per session" ;
  schema:description "The total token usage for an entire session is capped at 1M tokens" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-tokens> ;
  oplres:hasMaxValue "1000000"^^xsd:decimal ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/MaxUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantMaxSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerMaxSpecificChatUsers#this> ;
  wdrs:describedby <#source> .

oplres:max-prompt-interval-count-max a oplres:Restriction ;
  schema:name "Max 1000 prompts for interval 1 min" ;
  schema:description "Up to 1000 prompts" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:max-prompts-interval-count> ;
  oplres:hasMaxValue "60000"^^xsd:int ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/MaxUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantMaxSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerMaxSpecificChatUsers#this> ;
  wdrs:describedby <#source> .


# ------------------------------------------------------------------------------
# Module & Tool Restrictions
# ------------------------------------------------------------------------------

oplres:use-data-twingler a oplres:Restriction ;
  schema:name "Session Scoped to Data Twingler module" ;
  schema:description "OPAL Sessions that use the Data Twingler module" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:module> ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasRestrictedValue "data-twingler-config"^^xsd:string ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerEntryLevelSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerPlusSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerProSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerMaxSpecificChatUsers#this> ;
  wdrs:describedby <#source> .

oplres:use-support-assistant a oplres:Restriction ;
  schema:name "Session Scoped to the Support Assistant" ;
  schema:description "OPAL Sessions that use the Support Assistant" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:module> ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasRestrictedValue "virtuoso-support-assistant-config"^^xsd:string ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantEntryLevelSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantPlusSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantProSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantMaxSpecificChatUsers#this> ;
  wdrs:describedby <#source> .

# --- Requiring a value ---

# --- Entry Level Features ---

oplres:entry-level-assistant-access a oplres:Restriction ;
  schema:name "Entry Level assistant access" ;
  schema:description "Entry Level assistant access" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter	 <urn:oai:chat:module> ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyEntryLevelUsers#this> ;
  oplres:hasRestrictedValue "cello-config,data-twingler-config,opml-rss-news-reader,uda-support-assistant-config,virtuoso-support-assistant-config,data-twingler-uniprot" ;
  wdrs:describedby <#source> .

oplres:entry-level-assistant-access-tools a oplres:Restriction ;
  schema:name "Entry Level assistant access for tools" ;
  schema:description "Entry Level assistant access to the tools" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter	 <urn:oai:chat:enabled-tools> ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyEntryLevelUsers#this> ;
  oplres:hasRestrictedValue "UB.DBA.sparqlQuery,Demo.demo.execute_spasql_query,Demo.demo.execute_sql_query" ;
  oplres:hasMaxValue 1 ;
  wdrs:describedby <#source> .

# --- Plus Level Features ---

oplres:plus-level-assistant-access a oplres:Restriction ;
  schema:name "Plus assistant access" ;
  schema:description "Plus assistant access" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter	 <urn:oai:chat:module> ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyPlusUsers#this> ;
  oplres:hasRestrictedValue "cello-config,data-twingler-config,opml-rss-news-reader,uda-support-assistant-config,virtuoso-support-assistant-config,data-twingler-uniprot" ;
  wdrs:describedby <#source> .

oplres:plus-level-assistant-access-tools a oplres:Restriction ;
  schema:name "Plus assistant access for tools" ;
  schema:description "Plus assistant access to the tools" ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter	 <urn:oai:chat:enabled-tools> ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyPlusUsers#this> ;
  oplres:hasRestrictedValue "UB.DBA.sparqlQuery,Demo.demo.execute_spasql_query,Demo.demo.execute_sql_query,OAI.DBA.WEB_FETCH,OAI.DBA.SPONGE_URL,FCT.DBA.FacetSearch" ;
  oplres:hasMaxValue 2 ;
  wdrs:describedby <#source> .

# --- Pro Level Features ---

# --- Max Level Features ---

oplres:restrict-enable-api-keys a oplres:Restriction ;
  schema:name "Enable system-wide API key" ;
  schema:description "Allow use of system-wide API key." ;
  oplres:hasRestrictedResource <urn:oai:chat> ;
  oplres:hasRestrictedParameter <urn:oai:chat:enable-api-keys> ;
  oplres:hasRealm oplacl:DefaultRealm ;
  oplres:hasRestrictedValue "1"^^xsd:string ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/MaxUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/DataTwinglerMaxSpecificChatUsers#this> ;
  oplres:hasAgent <http://data.openlinksw.com/oplweb/group/SupportAssistantMaxSpecificChatUsers#this> ;
  wdrs:describedby <#source> .



# ==============================================================================
# Rules
# ==============================================================================

# --- Chat access rule ---

oplacl:chat-access-offers a acl:Authorization ;
  schema:name "Rule to allow access to /chat when an offer is purchased" ;
  acl:accessTo <urn:oai:chat> ;
  oplacl:hasAccessMode oplacl:Read, oplacl:Write ;
  acl:agent <http://data.openlinksw.com/oplweb/group/DataTwinglerEntryLevelSpecificChatUsers#this> ;
  acl:agent <http://data.openlinksw.com/oplweb/group/DataTwinglerPlusSpecificChatUsers#this> ;
  acl:agent <http://data.openlinksw.com/oplweb/group/DataTwinglerProSpecificChatUsers#this> ;
  acl:agent <http://data.openlinksw.com/oplweb/group/DataTwinglerMaxSpecificChatUsers#this> ;
  acl:agent <http://data.openlinksw.com/oplweb/group/SupportAssistantEntryLevelSpecificChatUsers#this> ;
  acl:agent <http://data.openlinksw.com/oplweb/group/SupportAssistantPlusSpecificChatUsers#this> ;
  acl:agent <http://data.openlinksw.com/oplweb/group/SupportAssistantProSpecificChatUsers#this> ;
  acl:agent <http://data.openlinksw.com/oplweb/group/SupportAssistantMaxSpecificChatUsers#this> ;
  acl:agent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyEntryLevelUsers#this> ;
  acl:agent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyPlusUsers#this> ;
  acl:agent <http://data.openlinksw.com/oplweb/group/BringYourOwnKeyProUsers#this> ;
  acl:agent <http://data.openlinksw.com/oplweb/group/MaxUsers#this> ;
  oplacl:hasRealm oplacl:DefaultRealm ;
  oplacl:hasScope oplacl:Query .


## --- OPAL Chat API Access
# ==============================================================================
# Conditional Group Definitions for each offer type
# ==============================================================================

<http://data.openlinksw.com/oplweb/group/ApiAccessEntryUsers#this> a oplacl:ConditionalGroup ;
    foaf:name "Users with API Access Entry Level License" ;
    oplacl:hasCondition [
      a oplacl:GroupCondition, oplacl:QueryCondition ;
      oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
        prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
        prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
        prefix schema:   <http://schema.org/>
        prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
        prefix owl:      <http://www.w3.org/2002/07/owl#>
        ask where {
          { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
          union
          { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
          graph ?cg {
            { ^{uri}^ oplprchs:madePurchase ?purchase . }
            union
            { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
            ?purchase oplprchs:contains ?offer ;
                      oplprchs:purchaseDate ?purchaseDate .
            ?offer a oplofr:ApiAccessEntryLevelOffer ;
                   schema:itemOffered ?license .
            ?license opllic:hasDuration ?duration .
            ?duration opllic:durationYears ?years .
            filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
          }
        }"""
     ] .

<http://data.openlinksw.com/oplweb/group/ApiAccessMediumUsers#this> a oplacl:ConditionalGroup ;
    foaf:name "Users with API Access Medium Level License" ;
    oplacl:hasCondition [
      a oplacl:GroupCondition, oplacl:QueryCondition ;
      oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
        prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
        prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
        prefix schema:   <http://schema.org/>
        prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
        prefix owl:      <http://www.w3.org/2002/07/owl#>
        ask where {
          {
            select ?license where {
              { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
              union
              { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
              graph ?cg {
                { ^{uri}^ oplprchs:madePurchase ?purchase . }
                union
                { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
                ?purchase oplprchs:contains ?offer ;
                          oplprchs:purchaseDate ?purchaseDate .
                ?offer a oplofr:ApiAccessMediumLevelOffer ;
                       schema:itemOffered ?license .
                ?license opllic:hasDuration ?duration .
                ?duration opllic:durationYears ?years .
                filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
              }
            } limit 1
          }
          filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
        }"""
     ] .

<http://data.openlinksw.com/oplweb/group/ApiAccessAdvancedUsers#this> a oplacl:ConditionalGroup ;
    foaf:name "Users with API Access Advanced Level License" ;
    oplacl:hasCondition [
      a oplacl:GroupCondition, oplacl:QueryCondition ;
      oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
        prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
        prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
        prefix schema:   <http://schema.org/>
        prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
        prefix owl:      <http://www.w3.org/2002/07/owl#>
        ask where {
          {
            select ?license where {
              { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
              union
              { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
              graph ?cg {
                { ^{uri}^ oplprchs:madePurchase ?purchase . }
                union
                { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
                ?purchase oplprchs:contains ?offer ;
                          oplprchs:purchaseDate ?purchaseDate .
                ?offer a oplofr:ApiAccessAdvancedLevelOffer ;
                       schema:itemOffered ?license .
                ?license opllic:hasDuration ?duration .
                ?duration opllic:durationYears ?years .
                filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
              }
            } limit 1
          }
          filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
        }"""
     ] .

<http://data.openlinksw.com/oplweb/group/ApiAccessMaxUsers#this> a oplacl:ConditionalGroup ;
    foaf:name "Users with API Access Max License" ;
    oplacl:hasCondition [
      a oplacl:GroupCondition, oplacl:QueryCondition ;
      oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
        prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
        prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
        prefix schema:   <http://schema.org/>
        prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
        prefix owl:      <http://www.w3.org/2002/07/owl#>
        ask where {
          {
            select ?license where {
              { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
              union
              { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
              graph ?cg {
                { ^{uri}^ oplprchs:madePurchase ?purchase . }
                union
                { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
                ?purchase oplprchs:contains ?offer ;
                          oplprchs:purchaseDate ?purchaseDate .
                ?offer a oplofr:ApiAccessMaxOffer ;
                       schema:itemOffered ?license .
                ?license opllic:hasDuration ?duration .
                ?duration opllic:durationYears ?years .
                filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
              }
            } limit 1
          }
          filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
        }"""
     ] .

# ==============================================================================
# Restrictions
# ==============================================================================

# ------------------------------------------------------------------------------
# Session & Token Limits
# ------------------------------------------------------------------------------

# --- Entry Level Limits ---

# Max Prompts per session: 20
# Max Input Tokens per prompt: 2,000
# Max Total Tokens per session: 4,000
# Rate limit per hour: 1500 (25 per minute)

oplres:api-entry-max-prompts a oplres:Restriction ;
    schema:name "API Entry: Max prompts per session" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-prompts> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "20"^^xsd:decimal ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessEntryUsers#this> .

oplres:api-entry-max-input-tokens a oplres:Restriction ;
    schema:name "API Entry: Max input tokens per prompt" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-prompt-tokens> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "2000"^^xsd:decimal ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessEntryUsers#this> .

oplres:api-entry-max-total-tokens a oplres:Restriction ;
    schema:name "API Entry: Max total tokens per session" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-tokens> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "4000"^^xsd:decimal ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessEntryUsers#this> .

oplres:api-entry-rate-limit a oplres:Restriction ;
    schema:name "API Entry: Max prompts per minute" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-prompts-interval-count> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "1500"^^xsd:int ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessEntryUsers#this> .

# --- Medium Level Limits ---

# Max Prompts per session: 200
# Max Input Tokens per prompt: 20,000
# Max Total Tokens per session: 40,000
# Rate limit per hour: 15000 (250 per minute)

oplres:api-medium-max-prompts a oplres:Restriction ;
    schema:name "API Medium: Max prompts per session" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-prompts> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "200"^^xsd:decimal ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessMediumUsers#this> .

oplres:api-medium-max-input-tokens a oplres:Restriction ;
    schema:name "API Medium: Max input tokens per prompt" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-prompt-tokens> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "20000"^^xsd:decimal ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessMediumUsers#this> .

oplres:api-medium-max-total-tokens a oplres:Restriction ;
    schema:name "API Medium: Max total tokens per session" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-tokens> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "40000"^^xsd:decimal ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessMediumUsers#this> .

oplres:api-medium-rate-limit a oplres:Restriction ;
    schema:name "API Medium: Max prompts per minute" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-prompts-interval-count> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "15000"^^xsd:int ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessMediumUsers#this> .

# --- Advanced Level Limits ---

# Max Prompts: 400
# Max Input Tokens: 100,000
# Max Total Tokens: 200,000
# Rate limit per hour: 30000 (500 per minute)

oplres:api-advanced-max-prompts a oplres:Restriction ;
    schema:name "API Advanced: Max prompts per session" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-prompts> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "400"^^xsd:decimal ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessAdvancedUsers#this> .

oplres:api-advanced-max-input-tokens a oplres:Restriction ;
    schema:name "API Advanced: Max input tokens per prompt" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-prompt-tokens> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "100000"^^xsd:decimal ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessAdvancedUsers#this> .

oplres:api-advanced-max-total-tokens a oplres:Restriction ;
    schema:name "API Advanced: Max total tokens per session" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-tokens> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "200000"^^xsd:decimal ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessAdvancedUsers#this> .

oplres:api-advanced-rate-limit a oplres:Restriction ;
    schema:name "API Advanced: Max prompts per minute" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-prompts-interval-count> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "30000"^^xsd:int ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessAdvancedUsers#this> .

# --- Max Level Limits ---

# Max Prompts per session: 1,000
# Max Input Tokens per prompt: 500,000
# Max Total Tokens per session: 1,000,000
# Rate limit per hour: 60000 (1000 per minute)

oplres:api-max-max-prompts a oplres:Restriction ;
    schema:name "API Max: Max prompts per session" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-prompts> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "1000"^^xsd:decimal ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessMaxUsers#this> .

oplres:api-max-max-input-tokens a oplres:Restriction ;
    schema:name "API Max: Max input tokens per prompt" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-prompt-tokens> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "500000"^^xsd:decimal ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessMaxUsers#this> .

oplres:api-max-max-total-tokens a oplres:Restriction ;
    schema:name "API Max: Max total tokens per session" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-tokens> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "1000000"^^xsd:decimal ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessMaxUsers#this> .

oplres:api-max-rate-limit a oplres:Restriction ;
    schema:name "API Max: Max prompts per minute" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:max-prompts-interval-count> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasMaxValue "60000"^^xsd:int ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessMaxUsers#this> .

# ------------------------------------------------------------------------------
# Feature & Tool Restrictions
# ------------------------------------------------------------------------------

# --- Entry Level Features ---

# SQL, SPASQL, Remote SPARQL, GraphQL

oplres:api-entry-tools a oplres:Restriction ;
    schema:name "API Entry: Included Features" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:enabled-tools> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasRestrictedValue "UB.DBA.sparqlQuery,Demo.demo.execute_spasql_query,Demo.demo.execute_sql_query" ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessEntryUsers#this> .

oplres:api-entry-modules a oplres:Restriction ;
    schema:name "API Entry: Included modules" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter  <urn:oai:chat:module> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasRestrictedValue "cello-config,data-twingler-config,opml-rss-news-reader,uda-support-assistant-config,virtuoso-support-assistant-config,data-twingler-uniprot" ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessEntryUsers#this> .

# --- Medium Level Features ---

# Adds: Sponge, Facet Search, Web Fetch

oplres:api-medium-tools a oplres:Restriction ;
    schema:name "API Medium: Included Features" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:enabled-tools> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasRestrictedValue "UB.DBA.sparqlQuery,Demo.demo.execute_spasql_query,Demo.demo.execute_sql_query,OAI.DBA.WEB_FETCH,OAI.DBA.SPONGE_URL,FCT.DBA.FacetSearch" ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessMediumUsers#this> .

oplres:api-medium-modules a oplres:Restriction ;
    schema:name "API Medium: Included modules" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter  <urn:oai:chat:module> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasRestrictedValue "cello-config,data-twingler-config,opml-rss-news-reader,uda-support-assistant-config,virtuoso-support-assistant-config,data-twingler-uniprot" ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessMediumUsers#this> .

# --- Advanced Level Features ---
# Adds: Agent Configs (Implied by Module Access, effectively Same tools as Medium + Config permission)

oplres:api-advanced-tools a oplres:Restriction ;
    schema:name "API Advanced: Included Features" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:enabled-tools> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasRestrictedValue "UB.DBA.sparqlQuery,Demo.demo.execute_spasql_query,Demo.demo.execute_sql_query,OAI.DBA.WEB_FETCH,OAI.DBA.SPONGE_URL,FCT.DBA.FacetSearch" ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessAdvancedUsers#this> .

# --- Max Level Features ---

# System Wide Access - Includes all

oplres:api-max-enable-keys a oplres:Restriction ;
    schema:name "API Max: Enable System-Wide Keys" ;
    oplres:hasRestrictedResource <urn:oai:chat> ;
    oplres:hasRestrictedParameter <urn:oai:chat:enable-api-keys> ;
    oplres:hasRealm oplacl:DefaultRealm ;
    oplres:hasRestrictedValue "1"^^xsd:string ;
    oplres:hasAgent <http://data.openlinksw.com/oplweb/group/ApiAccessMaxUsers#this> .

# ==============================================================================
# Rules
# ==============================================================================

# --- Chat access rule ---

oplacl:chat-access-api-offers a acl:Authorization ;
    schema:name "Rule to allow access to /chat when an offer is purchased" ;
    acl:accessTo <urn:oai:chat> ;
    oplacl:hasAccessMode oplacl:Read, oplacl:Write ;
    acl:agent <http://data.openlinksw.com/oplweb/group/ApiAccessEntryUsers#this> ;
    acl:agent <http://data.openlinksw.com/oplweb/group/ApiAccessMediumUsers#this> ;
    acl:agent <http://data.openlinksw.com/oplweb/group/ApiAccessAdvancedUsers#this> ;
    acl:agent <http://data.openlinksw.com/oplweb/group/ApiAccessMaxUsers#this> ;
    oplacl:hasRealm oplacl:DefaultRealm ;
    oplacl:hasScope oplacl:Query .

# --- Rule to access /oauth/clients.vsp ---

oplacl:oauth-apps-access-api-offers a acl:Authorization ;
    schema:name "Rule to allow access to oauth apps when an API offer is purchased" ;
    acl:accessTo <urn:virtuoso:access:oauth:apps> ;
    oplacl:hasAccessMode oplacl:Read, oplacl:Write ;
    acl:agent <http://data.openlinksw.com/oplweb/group/ApiAccessEntryUsers#this> ;
    acl:agent <http://data.openlinksw.com/oplweb/group/ApiAccessMediumUsers#this> ;
    acl:agent <http://data.openlinksw.com/oplweb/group/ApiAccessAdvancedUsers#this> ;
    acl:agent <http://data.openlinksw.com/oplweb/group/ApiAccessMaxUsers#this> ;
    oplacl:hasRealm oplacl:DefaultRealm ;
    oplacl:hasScope oplacl:OAuth .

## --- Graph Access ---
# ==============================================================================
# Conditonal Group Definitions for each offer type
# ==============================================================================

<http://data.openlinksw.com/oplweb/group/DemoGraphAccessUsers#this> a oplacl:ConditionalGroup ;
  foaf:name "Users identified using a NetID based Identifier who have purchased the demo graph access offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        {
          select ?license where {
            { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
            union
            { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
            graph ?cg {
              { ^{uri}^ oplprchs:madePurchase ?purchase . }
              union
              { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
              ?purchase oplprchs:contains ?offer ;
                        oplprchs:purchaseDate ?purchaseDate .
              ?offer a oplofr:DemoGraphAccessOffer ;
                     schema:itemOffered ?license .
              ?license opllic:hasDuration ?duration .
              ?duration opllic:durationYears ?years .
              filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
            }
          } limit 1
        }
        filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
      }"""
     ] .

<http://data.openlinksw.com/oplweb/group/DemoGraphAccessUsersWorldCupMeshup#this> a oplacl:ConditionalGroup ;
  foaf:name "Users identified using a NetID based Identifier who have purchased the demo graph access offer and whose license is in date" ;
  oplacl:hasCondition [
    a oplacl:GroupCondition, oplacl:QueryCondition ;
    oplacl:hasQuery """prefix oplprchs:  <http://www.openlinksw.com/ontology/purchases#>
      prefix opllic:   <http://www.openlinksw.com/ontology/licenses#>
      prefix oplofr:   <http://www.openlinksw.com/ontology/offers#>
      prefix schema:   <http://schema.org/>
      prefix oplshop:  <http://www.openlinksw.com/ontology/shop#>
      prefix owl:      <http://www.w3.org/2002/07/owl#>
      ask where {
        {
          select ?license where {
            { graph <urn:openlinksw.com.shop:registry> { ?shop oplshop:hasPurchaseCache ?cg } }
            union
            { bind(<urn:openlinksw.com:shop:purchases:cache> as ?cg) }
            graph ?cg {
              { ^{uri}^ oplprchs:madePurchase ?purchase . }
              union
              { ?o owl:sameAs ^{uri}^ ; oplprchs:madePurchase ?purchase . }
              ?purchase oplprchs:contains ?offer ;
                        oplprchs:purchaseDate ?purchaseDate .
              ?offer a oplofr:DemoGraphAccessOfferWorldCupMeshup ;
                     schema:itemOffered ?license .
              ?license opllic:hasDuration ?duration .
              ?duration opllic:durationYears ?years .
              filter (bif:dateadd ('day', xsd:integer(?years) * 365, ?purchaseDate) > bif:now()) .
            }
          } limit 1
        }
        filter (sql:stripe_customer_has_active_product_subscription (str(^{uri}^), ?license) > 0) .
      }"""
     ] .

# ==============================================================================
# Restrictions
# ==============================================================================

# --- Limits ---

# ==============================================================================
# Rules
# ==============================================================================

# --- Graph access rule ---

oplacl:demo-graph-access a acl:Authorization ;
  schema:name "Rule to allow access to the demo graph" ;
  acl:accessTo <urn:demo:graph> ;
  oplacl:hasAccessMode oplacl:Read ;
  oplacl:hasRealm oplacl:DefaultRealm ;
  oplacl:hasScope oplacl:PrivateGraphs ;
  acl:agent <http://data.openlinksw.com/oplweb/group/DemoGraphAccessUsers#this> ;
  wdrs:describedby <#source> .

oplacl:demo-graph-access-world-cup-meshup a acl:Authorization ;
  schema:name "Rule to allow access to the <https://linkeddata.uriburner.com/DAV/demos/daas_paid/world-cup-2026-country-player-guide-meshup-gpt5-chat-1.ttl> graph" ;
  acl:accessTo <https://linkeddata.uriburner.com/DAV/demos/daas_paid/world-cup-2026-country-player-guide-meshup-gpt5-chat-1.ttl> ;
  acl:accessTo <https://linkeddata.uriburner.com/DAV/demos/daas/world-cup-2026-meshup-kg-1.ttl> ;
  oplacl:hasAccessMode oplacl:Read ;
  oplacl:hasRealm oplacl:DefaultRealm ;
  oplacl:hasScope oplacl:PrivateGraphs ;
  acl:agent <http://data.openlinksw.com/oplweb/group/DemoGraphAccessUsersWorldCupMeshup#this> ;
  wdrs:describedby <#source> .


## --- File Access ---
# ==============================================================================
# Restrictions
# ==============================================================================

# --- Limits ---

# ==============================================================================
# Rules
# ==============================================================================

# --- File access rule ---

# -- TTL file also needs rule to allow the file access users to use /sparql to describe ttl files using the faceted browser?
# -- I have not been able to make this work

oplacl:fct-access a acl:Authorization ;
  schema:name "Rule to allow access to /sparql for user who purchase file access" ;
  acl:accessTo <urn:virtuoso:access:sparql> ;
  oplacl:hasAccessMode oplacl:Read ;
  oplacl:hasRealm oplacl:DefaultRealm ;
  oplacl:hasScope oplacl:Query ;
  acl:agent <http://data.openlinksw.com/oplweb/group/XYZFileAccessUsers#this> ;
  wdrs:describedby <#source> .


## Turtle End ##
