refactor(infra-options): unify per-service data into four-facet schema
infra.services.<name> now carries port + web + storage + identity as
optional facets, replacing the previously-split:
- infra.services.<n>.port (this file)
- infra.storage.services.<n> (storage_locations.nix, deleted)
- infra.users.serviceToUserMap (users.nix, dropped)
web.{host,url} are derived from {subdomain, domain}, so consumers no
longer string-concatenate the URL. Domain itself is a free-form string
set by the deployment-routing module — not an enum, so service routing
(e.g. immich's eventual flip from internal to public) is a one-line
change without false swappability framing.
Storage facet collapses {dataDir, mediaDir, musicDir, stateDir} into
just {base, backupDir?, nfsExport, allowedIpRange}; per-service content
subdirs live in the service's own module, derived locally from base.
Duplicate-port assertion now ignores nulls; duplicate-uid/gid assertions
added (replaces the same check in nix-config's personal_users.nix).
nfs-server module + lib/nfs.nix updated to read from the new shape.