@prefix xp: <https://xptio.com/ontology#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix schema: <https://schema.org/> .

<https://xptio.com/ontology> a owl:Ontology ;
  rdfs:label "xptio site ontology"@en ;
  rdfs:comment "Vocabulary for the xptio.com site: the organisation, its services, way of working, articles and the people behind it. Aligned with schema.org."@en ;
  dcterms:publisher <https://xptio.com/#organization> ;
  rdfs:seeAlso <https://xptio.com/llms.txt> ;
  owl:versionInfo "1.0" .

# schema.org terms used here, declared so the ontology stays in OWL 2 DL
schema:url a owl:AnnotationProperty .
schema:provider a owl:ObjectProperty .
schema:about a owl:ObjectProperty .
schema:isPartOf a owl:ObjectProperty .
schema:knowsAbout a owl:ObjectProperty .
schema:position a owl:DatatypeProperty .
dcterms:publisher a owl:AnnotationProperty .
dcterms:created a owl:AnnotationProperty .
dcterms:creator a owl:AnnotationProperty .

# Classes
xp:Organisation a owl:Class ;
  rdfs:label "Organisation"@en ;
  rdfs:comment "A business that offers software engineering services."@en ;
  rdfs:subClassOf schema:Organization .
xp:Service a owl:Class ;
  rdfs:label "Service"@en ;
  rdfs:comment "A kind of work the organisation offers."@en ;
  rdfs:subClassOf schema:Service .
xp:FocusArea a owl:Class ;
  rdfs:label "Focus area"@en ;
  rdfs:comment "A theme a service concentrates on, such as accessibility or rollback."@en ;
  rdfs:subClassOf schema:DefinedTerm .
xp:Step a owl:Class ;
  rdfs:label "Step"@en ;
  rdfs:comment "One stage of the way of working; steps repeat in small cycles."@en ;
  rdfs:subClassOf schema:HowToStep .
xp:Principle a owl:Class ;
  rdfs:label "Principle"@en ;
  rdfs:comment "A standard every piece of work is held to."@en ;
  rdfs:subClassOf schema:DefinedTerm .
xp:Section a owl:Class ;
  rdfs:label "Site section"@en ;
  rdfs:comment "A top-level part of the website, served by its own application."@en ;
  rdfs:subClassOf schema:WebPage .
xp:Article a owl:Class ;
  rdfs:label "Article"@en ;
  rdfs:comment "A blog article."@en ;
  rdfs:subClassOf schema:BlogPosting .
xp:Topic a owl:Class ;
  rdfs:label "Topic"@en ;
  rdfs:comment "A tag or category an article is filed under."@en ;
  rdfs:subClassOf schema:DefinedTerm .
xp:Person a owl:Class ;
  rdfs:label "Person"@en ;
  rdfs:comment "A person whose CV the site publishes."@en ;
  rdfs:subClassOf schema:Person .
xp:Skill a owl:Class ;
  rdfs:label "Skill"@en ;
  rdfs:comment "A technology or practice a person knows."@en ;
  rdfs:subClassOf schema:DefinedTerm .
xp:Role a owl:Class ;
  rdfs:label "Role"@en ;
  rdfs:comment "A position a person held at an employer."@en ;
  rdfs:subClassOf schema:OrganizationRole .

xp:Service owl:disjointWith xp:Principle , xp:Step , xp:Section .
xp:Article owl:disjointWith xp:Section .

# Object properties
xp:offers a owl:ObjectProperty ;
  rdfs:label "offers"@en ;
  rdfs:comment "The organisation offers this service."@en ;
  rdfs:domain xp:Organisation ;
  rdfs:range xp:Service .
xp:provider a owl:ObjectProperty , owl:FunctionalProperty ;
  rdfs:label "provider"@en ;
  rdfs:comment "The organisation that offers the service."@en ;
  rdfs:domain xp:Service ;
  rdfs:range xp:Organisation .
xp:provider owl:inverseOf xp:offers ;
  rdfs:subPropertyOf schema:provider .
xp:focusesOn a owl:ObjectProperty ;
  rdfs:label "focusesOn"@en ;
  rdfs:comment "A focus area of the service."@en ;
  rdfs:domain xp:Service ;
  rdfs:range xp:FocusArea .
xp:followsStep a owl:ObjectProperty ;
  rdfs:label "followsStep"@en ;
  rdfs:comment "A step of the way the organisation works."@en ;
  rdfs:domain xp:Organisation ;
  rdfs:range xp:Step .
xp:nextStep a owl:ObjectProperty , owl:FunctionalProperty ;
  rdfs:label "nextStep"@en ;
  rdfs:comment "The step that comes after this one; the last leads back to the first."@en ;
  rdfs:domain xp:Step ;
  rdfs:range xp:Step .
xp:holdsTo a owl:ObjectProperty ;
  rdfs:label "holdsTo"@en ;
  rdfs:comment "A principle the organisation holds its work to."@en ;
  rdfs:domain xp:Organisation ;
  rdfs:range xp:Principle .
xp:hasSection a owl:ObjectProperty ;
  rdfs:label "hasSection"@en ;
  rdfs:comment "A section of the organisation website."@en ;
  rdfs:domain xp:Organisation ;
  rdfs:range xp:Section .
xp:hasTopic a owl:ObjectProperty ;
  rdfs:label "hasTopic"@en ;
  rdfs:comment "A tag or category of the article."@en ;
  rdfs:domain xp:Article ;
  rdfs:range xp:Topic .
xp:hasTopic rdfs:subPropertyOf schema:about .
xp:publishedIn a owl:ObjectProperty ;
  rdfs:label "publishedIn"@en ;
  rdfs:comment "The site section that publishes the article."@en ;
  rdfs:domain xp:Article ;
  rdfs:range xp:Section .
xp:publishedIn rdfs:subPropertyOf schema:isPartOf .
xp:knows a owl:ObjectProperty ;
  rdfs:label "knows"@en ;
  rdfs:comment "A skill the person has."@en ;
  rdfs:domain xp:Person ;
  rdfs:range xp:Skill .
xp:knows rdfs:subPropertyOf schema:knowsAbout .
xp:heldRole a owl:ObjectProperty ;
  rdfs:label "heldRole"@en ;
  rdfs:comment "A position the person held."@en ;
  rdfs:domain xp:Person ;
  rdfs:range xp:Role .

# Datatype properties
xp:position a owl:DatatypeProperty , owl:FunctionalProperty ;
  rdfs:label "position"@en ;
  rdfs:comment "Order of the step in the cycle, from 1."@en ;
  rdfs:domain xp:Step ;
  rdfs:range xsd:positiveInteger .
xp:position rdfs:subPropertyOf schema:position .
xp:readingMinutes a owl:DatatypeProperty , owl:FunctionalProperty ;
  rdfs:label "readingMinutes"@en ;
  rdfs:comment "Estimated reading time in minutes."@en ;
  rdfs:domain xp:Article ;
  rdfs:range xsd:positiveInteger .

# Individuals
<https://xptio.com/#organization> a xp:Organisation , owl:NamedIndividual ;
  rdfs:label "xptio" ;
  rdfs:comment "Dependable backend and web software, built to last."@en ;
  schema:url <https://xptio.com/> ;
  xp:offers xp:service-backend-services-and-apis ;
  xp:offers xp:service-web-applications ;
  xp:offers xp:service-integrations ;
  xp:offers xp:service-operations ;
  xp:offers xp:service-modernisation ;
  xp:followsStep xp:step-understand ;
  xp:followsStep xp:step-design ;
  xp:followsStep xp:step-build ;
  xp:followsStep xp:step-run ;
  xp:holdsTo xp:principle-reliable-by-default ;
  xp:holdsTo xp:principle-secure-from-the-start ;
  xp:holdsTo xp:principle-accessible-to-everyone ;
  xp:holdsTo xp:principle-measured-not-guessed ;
  xp:holdsTo xp:principle-plain-and-documented ;
  xp:holdsTo xp:principle-respectful-of-privacy ;
  xp:hasSection xp:section-home , xp:section-blog , xp:section-privacy .

xp:service-backend-services-and-apis a xp:Service , owl:NamedIndividual ;
  rdfs:label "Backend services and APIs"@en ;
  rdfs:comment "Services with clear contracts, versioned interfaces and the tests that keep them honest."@en ;
  xp:provider <https://xptio.com/#organization> ;
  xp:focusesOn xp:focus-rest , xp:focus-messaging , xp:focus-data-models .

xp:service-web-applications a xp:Service , owl:NamedIndividual ;
  rdfs:label "Web applications"@en ;
  rdfs:comment "Fast, accessible applications that work on every screen and degrade gracefully without JavaScript."@en ;
  xp:provider <https://xptio.com/#organization> ;
  xp:focusesOn xp:focus-accessibility , xp:focus-performance , xp:focus-design-systems .

xp:service-integrations a xp:Service , owl:NamedIndividual ;
  rdfs:label "Integrations"@en ;
  rdfs:comment "Connecting systems that were never meant to talk: imports, exports, queues and the edge cases between them."@en ;
  xp:provider <https://xptio.com/#organization> ;
  xp:focusesOn xp:focus-interoperability , xp:focus-validation , xp:focus-reconciliation .

xp:service-operations a xp:Service , owl:NamedIndividual ;
  rdfs:label "Operations"@en ;
  rdfs:comment "Deployments that roll back on their own, logs worth reading and alerts that mean something."@en ;
  xp:provider <https://xptio.com/#organization> ;
  xp:focusesOn xp:focus-ci-cd , xp:focus-observability , xp:focus-rollback .

xp:service-modernisation a xp:Service , owl:NamedIndividual ;
  rdfs:label "Modernisation"@en ;
  rdfs:comment "Moving long-lived systems forward in small, safe steps instead of risky rewrites."@en ;
  xp:provider <https://xptio.com/#organization> ;
  xp:focusesOn xp:focus-refactoring , xp:focus-migration , xp:focus-testing .

xp:focus-rest a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "REST"@en .
xp:focus-messaging a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "Messaging"@en .
xp:focus-data-models a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "Data models"@en .
xp:focus-accessibility a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "Accessibility"@en .
xp:focus-performance a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "Performance"@en .
xp:focus-design-systems a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "Design systems"@en .
xp:focus-interoperability a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "Interoperability"@en .
xp:focus-validation a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "Validation"@en .
xp:focus-reconciliation a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "Reconciliation"@en .
xp:focus-ci-cd a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "CI/CD"@en .
xp:focus-observability a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "Observability"@en .
xp:focus-rollback a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "Rollback"@en .
xp:focus-refactoring a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "Refactoring"@en .
xp:focus-migration a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "Migration"@en .
xp:focus-testing a xp:FocusArea , owl:NamedIndividual ;
  rdfs:label "Testing"@en .

xp:step-understand a xp:Step , owl:NamedIndividual ;
  rdfs:label "Understand: Start from the problem"@en ;
  rdfs:comment "Who uses the system, what must never break, and what “done” means."@en ;
  xp:position "1"^^xsd:positiveInteger ;
  xp:nextStep xp:step-design .

xp:step-design a xp:Step , owl:NamedIndividual ;
  rdfs:label "Design: Make the shape visible"@en ;
  rdfs:comment "Interfaces, data and failure modes written down before the code."@en ;
  xp:position "2"^^xsd:positiveInteger ;
  xp:nextStep xp:step-build .

xp:step-build a xp:Step , owl:NamedIndividual ;
  rdfs:label "Build: Ship in small slices"@en ;
  rdfs:comment "Each change tested, reviewed and deployable on its own."@en ;
  xp:position "3"^^xsd:positiveInteger ;
  xp:nextStep xp:step-run .

xp:step-run a xp:Step , owl:NamedIndividual ;
  rdfs:label "Run: Own it in production"@en ;
  rdfs:comment "Monitoring, security updates and fixes after launch."@en ;
  xp:position "4"^^xsd:positiveInteger ;
  xp:nextStep xp:step-understand .

xp:principle-reliable-by-default a xp:Principle , owl:NamedIndividual ;
  rdfs:label "Reliable by default"@en ;
  rdfs:comment "Validation at every boundary, atomic writes, health checks and automatic rollback."@en .

xp:principle-secure-from-the-start a xp:Principle , owl:NamedIndividual ;
  rdfs:label "Secure from the start"@en ;
  rdfs:comment "Least privilege, strict content security policies and no secrets in code."@en .

xp:principle-accessible-to-everyone a xp:Principle , owl:NamedIndividual ;
  rdfs:label "Accessible to everyone"@en ;
  rdfs:comment "WCAG 2.1 AA, keyboard paths and reduced-motion versions designed, not dropped."@en .

xp:principle-measured-not-guessed a xp:Principle , owl:NamedIndividual ;
  rdfs:label "Measured, not guessed"@en ;
  rdfs:comment "Performance budgets and automated checks on every change."@en .

xp:principle-plain-and-documented a xp:Principle , owl:NamedIndividual ;
  rdfs:label "Plain and documented"@en ;
  rdfs:comment "Boring technology, readable code and decisions recorded where the next person looks."@en .

xp:principle-respectful-of-privacy a xp:Principle , owl:NamedIndividual ;
  rdfs:label "Respectful of privacy"@en ;
  rdfs:comment "Collect little, keep less, and say clearly what is stored."@en .

xp:section-home a xp:Section , owl:NamedIndividual ;
  rdfs:label "Home"@en ;
  schema:url <https://xptio.com/> .
xp:section-blog a xp:Section , owl:NamedIndividual ;
  rdfs:label "Blog"@en ;
  schema:url <https://xptio.com/blog/> .
xp:section-privacy a xp:Section , owl:NamedIndividual ;
  rdfs:label "Privacy"@en ;
  schema:url <https://xptio.com/privacy/> .
