To add to the discussion, and not suggesting that this is the best solution, here's a quick summary of the PanSTARRS solution for this. The main filter specifier was the photocode, defined in a table like:
#code name type zeropt airmass_slope airmass_offset equiv ...
1 g sec 0.000 0.00 0.00 -
10001 GPC1.g.XY01 dep 24.563 -0.147 0.000 1
11000 GPC1.g.SkyChip dep 25.000 0.000 0.000 1
20000 HSC.g.00 dep 26.783 -0.150 0.000 1
The "AbstractFilter" is defined by a low-photcode entry, which have their type set to "sec" (for historical reasons), and have no zeropoint, airmass, or color terms (omitted here for clarity), as they are the "platonic ideals".
All observed filters ("PhysicalFilters"/type="dep") are defined in based on camera/sensor/AbstractFilter tuples, which have the zpt/airm/color terms to define how the instrumental magnitudes should match their "equiv" photcode. These zpt/airm/color terms serve the purpose of transmission curves, and are used for the initial raw data calibration. During the full catalog calibration, these terms are included as part of the fit, allowing each sensor to have different responses and to allow for time variations.
The final internal catalog links each observation to the observed photcode, which in turn uses the best fit terms to link to the equivalent photcode. This set of equivalent photcode measurements is then used to define the average photometric parameters.
The "SkyChip" entry is used for stacked products, which have a defined set of photometric parameters, and all inputs scaled from the detector-specific values. In the perfect case, each image would be scaled using the final best fit parameters to ensure that the stacked image exactly matches the SkyChip photcode. In practice, the stacks are constructed from the previous iteration of the parameters.
Photcode indices are integers and unique, roughly generated as:
photcode = camera_B + 10^N * filter + sensor
For GPC1: B=10000, N=2; HSC: B=20000,N=3; MEGACAM: B=100,N=1; etc. This ordering is stable and more human readable than strict autoincrements, but it does not allow filter subtraction. New filters can be added, but the updated photcode table needs to be included/referenced with any data that uses the new filters.
FWIW, I've had to deal with some of these issues in a mostly pragmatic and ungeneralizable way within FGCM (sorry). I have a disctinction between a filter which is essentially the PhysicalFilter here (it's an object that sits in the beam and has some transparency qualities, etc.) and a band (I believe akin to the Gen3 AbstractFilter) which is a platonic ideal of something that is (say) "r-band-like". Maybe not completely obvious/clear, but in general we will want to make sure that we have a strict definition/usage recommendation when somebody says "r-band" wrt to these concepts in the stack does that refer to the PhysicalFilter or the `AbstractFilter`?
Relatedly, my filter/PhysicalFilter can vary over the focal plane, and/or with time, etc. But my band/AbstractFilter cannot ... it defines the standard to which everything else is calibrated.
However, in my typical use I want to know what the transmission curve is for the filter/band. Well, sometimes I just want the name and an index, but if I'm making use of it then I want to know what the transmission is. However, I can see that carrying around all these data at all times might be inconvenient. But I'd want to make sure that "load the transmission curve" is as easy and transparent as possible.