Importers mostly define migration paths

Previously, import had been little more than iterating through each
record in the existing community site and testing to see if it needed to
be imported. This is pretty wasteful, and we started moving towards an
approach that would only attempt to import records which we could
reasonably assume had not been imported yet.

As this approach matured, it made less sense to have each community site
record know about how it would be imported into Supermarket. And so we
arrive here, where each import defines the "source" record type, the
"desination" record type, and the SQL query one would use to fetch each
importable ID. Outside of a couple notable edge-cases, this allows us to
efficiently figure out which community site records have not yet been
imported, and to attempt to import only those records.

One consequence of this is that we can remove most individual
completeness checks. In almost every case, we only ever feed the import
data that has not yet been imported; and, if we accidentally feed it
duplicate data, the individual import will violate some constraint in
the Supermarket database.

The main exceptions are Category records, and CookbookDependency
records. The former we don't prefilter because there are so few, and the
latter we double-check because there are a few duplicate cookbook
versions on the existing community site, and it's easier to skip them
than to work our way around attempting to import them.
Add cull tasks

After we've run the initial import, the community site will inevitably
diverge in a way that requires us to delete records we've already
imported into Supermarket. The "cull" tasks serve that purpose.
The import progress bar shows completed/total
Add a parent task to perform data migrations